Skip to content

Commit 17d5b31

Browse files
authored
Merge pull request #1872 from Hack23/copilot/investigate-replace-economic-indicators
Adopt IMF data alongside World Bank (Economic Data Contract v2.0)
2 parents 4f955ba + 6b89a1a commit 17d5b31

46 files changed

Lines changed: 2861 additions & 114 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/agents/data-pipeline-specialist.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ Repo-level agents do **not** declare `mcp-servers:` — MCP is configured once i
336336
|--------|---------|
337337
| `github` (Insiders HTTP) | Full toolset incl. `assign_copilot_to_issue`, `create_pull_request_with_copilot`, `get_copilot_job_status`, issues, PRs, projects, actions, security alerts, discussions |
338338
| `riksdag-regering` (HTTP) | 32+ tools for Swedish Parliament/Government open data |
339-
| `scb` / `world-bank` (local) | Statistics Sweden PxWeb v2 and World Bank indicators |
339+
| `scb` / `world-bank` (local) | Statistics Sweden PxWeb v2 and World Bank indicators (WB narrowed to governance/environment/social residue in v2.0 contract) |
340+
| `imf` (TypeScript client: `scripts/imf-client.ts` + `scripts/imf-fetch.ts`, no MCP) | IMF Datamapper (WEO) + SDMX 3.0 passthrough (IFS/BOP/FM/GFS/DOTS). Primary macro/fiscal/monetary source with projections; invoke via `bash` (`tsx scripts/imf-fetch.ts compare|weo|sdmx …`), prefer the `compare` subcommand for multi-country batches, respect 10 req/5 s rate limit (client retries 3× on 429), cache via `--persist`/`persistIMFData()` under `analysis/data/imf/{indicator}/{country}.json`. See `analysis/imf/README.md` + Economic Data Contract v2.0. |
340341
| `filesystem` / `memory` / `sequential-thinking` / `playwright` | Local helpers (scoped FS, persistent memory, structured reasoning, headless browser) |
341342

342343
MCP config changes are **Normal Changes** needing CEO approval per the [Secure Development Policy](https://github.com/Hack23/ISMS-PUBLIC/blob/main/Secure_Development_Policy.md) curator-agent governance section.

.github/agents/intelligence-operative.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ Repo agents do **not** configure MCP servers — MCP is defined once in [`.githu
4848
|--------|---------|
4949
| **riksdag-regering** (HTTP) | 32+ tools for Swedish Parliament/Government open data |
5050
| **scb** (local) | Statistics Sweden PxWeb v2 API |
51-
| **world-bank** (local) | World Bank indicators (GDP, debt, social) |
51+
| **world-bank** (local) | World Bank indicators — governance (WGI), environment, long-horizon social/education residue |
52+
| **imf** (TypeScript client via `bash` + `tsx scripts/imf-fetch.ts`, no MCP) | IMF Datamapper (WEO) + SDMX 3.0 passthrough (IFS/BOP/FM/GFS/DOTS) with T+5 projections; primary source for fresh macro/fiscal/monetary figures (see `analysis/imf/` + Economic Data Contract v2.0) |
5253
| **github** (Insiders HTTP) | Full GitHub toolset incl. `assign_copilot_to_issue`, `create_pull_request_with_copilot`, `get_copilot_job_status` |
5354
| **filesystem / memory / sequential-thinking / playwright** | Local helpers |
5455

.github/agents/news-journalist.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ tools: ["*"]
1818

1919
## 🔴 AI FIRST Quality Principle
2020

21-
> **Never accept first-pass quality. Minimum 2 complete iterations for every article. After Pass 1, read ALL output back and improve: strengthen lede with named actors, deepen "Why It Matters" (no boilerplate), add evidence (dok_id, vote counts, named MPs), broaden perspectives (6+ stakeholder groups), add economic context (SCB, World Bank), verify forward indicators (dates, triggers, decision-makers). Spend ALL allocated time — shallow reporting is rejected.**
21+
> **Never accept first-pass quality. Minimum 2 complete iterations for every article. After Pass 1, read ALL output back and improve: strengthen lede with named actors, deepen "Why It Matters" (no boilerplate), add evidence (dok_id, vote counts, named MPs), broaden perspectives (6+ stakeholder groups), add economic context (SCB, IMF — WEO/FM projections where relevant — World Bank for governance/environment residue), verify forward indicators (dates, triggers, decision-makers). Spend ALL allocated time — shallow reporting is rejected.**
2222
2323
---
2424

.github/aw/ECONOMIC_DATA_CONTRACT.md

Lines changed: 162 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
# Economic Data Contract — Agentic Workflows (v1.0)
1+
# Economic Data Contract — Agentic Workflows (v2.0)
22

3-
> **Single source of truth** for live World Bank / SCB data, Chart.js
3+
> **Single source of truth** for live IMF / World Bank / SCB data, Chart.js
44
> visualisations, and AI commentary in every news article.
55
> Consumed by `scripts/validate-economic-context.ts` and referenced
66
> (by link) from every `news-*.md` agentic workflow.
77
8+
> **Schema v2.0 (2026-04-20)** — additive. Adds IMF (accessed via the
9+
> repo's pure-TypeScript `scripts/imf-client.ts` + `scripts/imf-fetch.ts`
10+
> CLI, no Python MCP) as a first-class primary source for macro, fiscal,
11+
> monetary, and external-sector indicators. World Bank remains
12+
> authoritative for governance (WGI), environment, and long-horizon
13+
> social/education residue. SCB remains the Swedish primary source.
14+
> v1 artefacts remain valid; the validator accepts both shapes during
15+
> the 2026-04-20 → 2026-05-31 grace window.
16+
817
---
918

1019
## Why this contract exists
@@ -51,22 +60,28 @@ where `{analysisSubfolder}` maps from the kebab article-type slug via
5160

5261
**Schema**: `analysis/schemas/economic-data.schema.json`.
5362

54-
**Shape**:
63+
**Shape** (v2.0 — additive over v1):
5564

5665
```jsonc
5766
{
58-
"version": "1.0",
67+
"version": "2.0",
5968
"articleType": "committee-reports",
60-
"date": "2026-04-17",
69+
"date": "2026-04-20",
6170
"policyDomains": ["fiscal policy", "labor market"],
6271
"dataPoints": [
63-
{ "countryCode": "SWE", "countryName": "Sweden", "indicatorId": "NY.GDP.MKTP.KD.ZG", "date": "2024", "value": 0.82 },
64-
{ "countryCode": "DNK", "countryName": "Denmark", "indicatorId": "NY.GDP.MKTP.KD.ZG", "date": "2024", "value": 1.75 }
72+
// IMF (WEO projections permitted for look-ahead article types)
73+
{ "countryCode": "SWE", "countryName": "Sweden", "indicatorId": "NGDP_RPCH", "date": "2025", "value": 1.9, "provider": "imf", "projection": false },
74+
{ "countryCode": "SWE", "countryName": "Sweden", "indicatorId": "GGXWDG_NGDP", "date": "2027", "value": 32.4, "provider": "imf", "projection": true, "projectionVintage": "WEO-2026-04" },
75+
// World Bank (governance / environment / social residue)
76+
{ "countryCode": "SWE", "countryName": "Sweden", "indicatorId": "CC.EST", "date": "2023", "value": 2.1, "provider": "worldBank", "projection": false },
77+
// SCB (Swedish primary source)
78+
{ "countryCode": "SWE", "countryName": "Sweden", "indicatorId": "TAB1291", "date": "2025-02", "value": 405.2, "provider": "scb", "projection": false }
6579
],
66-
"commentary": "Sweden's 0.82% 2024 GDP growth lags Denmark (1.75%) and Norway (1.1%), framing the committee's fiscal debate against a prolonged slowdown. Health expenditure at 11.2% of GDP (2022, top 3 Nordic) keeps SoU-2024/25:1 in focus.",
80+
"commentary": "IMF projects Sweden's general government gross debt at 32.4 % of GDP in 2027 (WEO Apr-2026, GGXWDG_NGDP), giving SkU-2025/26:12 fiscal headroom absent in 2022 (38 %). Control-of-corruption remains strong at 2.1 (WGI 2023).",
6781
"source": {
68-
"worldBank": ["NY.GDP.MKTP.KD.ZG", "FP.CPI.TOTL.ZG", "SL.UEM.TOTL.ZS"],
69-
"scb": ["TAB1291"]
82+
"worldBank": ["CC.EST"],
83+
"scb": ["TAB1291"],
84+
"imf": ["WEO:NGDP_RPCH", "WEO:GGXWDG_NGDP"]
7085
}
7186
}
7287
```
@@ -78,65 +93,103 @@ where `{analysisSubfolder}` maps from the kebab article-type slug via
7893
- `commentary` MUST cite 2–3 concrete numeric values that appear in
7994
`dataPoints` (the validator enforces only a word count; the human
8095
review + multi-dim quality score enforces the citation).
81-
- `source.worldBank` / `source.scb` MUST list the IDs actually queried.
96+
- At least one of `source.worldBank` / `source.scb` / `source.imf` MUST
97+
be non-empty (previously only `worldBank`/`scb` counted).
98+
- When any `dataPoint.projection === true`, it MUST carry a
99+
`projectionVintage` tag (e.g. `"WEO-2026-04"`, `"FM-2026-04"`).
100+
Projection values MAY only be cited in article commentary for the
101+
**look-ahead allow-list**: `week-ahead`, `month-ahead`,
102+
`weekly-review`, `monthly-review`. Daily types (`committee-reports`,
103+
`propositions`, `motions`, `interpellations`, `evening-analysis`)
104+
MAY include projection values in `dataPoints` for context but MUST
105+
NOT quote them as definitive forward-looking claims in commentary.
82106
- File MUST validate against
83107
`analysis/schemas/economic-data.schema.json`.
84108

109+
### v1 back-compat
110+
111+
A v1 artefact (no `source.imf[]`, no `provider`/`projection` on data
112+
points) is still accepted. The loader fills defaults
113+
(`provider: "worldBank"`, `projection: false`). New workflows SHOULD
114+
emit v2.
115+
85116
---
86117

87118
## MCP tool contract
88119

89120
Step 2.6 of every `news-*.md` workflow MUST perform these MCP calls
90-
**before** writing `economic-data.json`:
121+
**before** writing `economic-data.json`. The order of provider
122+
preference is:
123+
124+
1. **IMF** — macro (GDP, inflation, unemployment), fiscal (debt, deficit,
125+
revenue, expenditure), monetary, external sector. WEO projections
126+
extend to T+5 and MUST be used for look-ahead article types.
127+
2. **SCB** — Swedish-specific ground truth that IMF does not carry
128+
(household consumption patterns, regional data, high-frequency
129+
monthly tables).
130+
3. **World Bank** — governance (WGI: CC.EST, RL.EST, VA.EST, GE.EST,
131+
RQ.EST, PV.EST), environment (CO2, forest area, renewables), and
132+
long-horizon social/education indicators IMF does not cover.
91133

92134
### 1. Map documents → policy domains → indicators
93135

94136
```
95-
view analysis/worldbank/indicators-inventory.json
137+
view analysis/economic-indicators-inventory.json
96138
```
97139

98-
Select every indicator that has a `mcpTool` field and whose
99-
`committees`/`policyAreas` match the day's source documents. Prioritise
100-
the committee-specific matrix in `SHARED_PROMPT_PATTERNS.md` §"World
101-
Bank Indicator Reference".
140+
Each indicator entry carries a `provider` field (`imf` | `worldBank` |
141+
`scb`), plus IMF-specific fields (`imfDatabase`, `imfIndicatorCode`,
142+
`imfDimensionFilters`, `projectionHorizon`) when the primary provider
143+
is IMF. Select every indicator whose `committees` / `policyAreas`
144+
match the day's source documents. The legacy inventory at
145+
`analysis/worldbank/indicators-inventory.json` is retained as an
146+
append-only reference during the migration window.
102147

103-
### 2. Query World Bank (Sweden + Nordic peers)
148+
### 2. Query IMF (Sweden + Nordic peers) — PRIMARY for macro/fiscal/monetary
104149

105-
Required calls, retried 3× on failure (see Risks):
150+
Via the repository's pure-TypeScript client `scripts/imf-client.ts`,
151+
exposed to agentic workflows through the thin `scripts/imf-fetch.ts`
152+
CLI. No Python MCP / `uvx` runtime is involved; all IMF traffic goes
153+
directly to `data.imf.org`, `api.imf.org`, and `www.imf.org` on the
154+
firewall allowlist.
106155

107-
```
108-
# Sweden — full 10-year series for the primary domains
109-
get-economic-data(countryCode="SE", indicator="GDP_GROWTH", years=10)
110-
get-economic-data(countryCode="SE", indicator="INFLATION", years=10)
111-
get-economic-data(countryCode="SE", indicator="UNEMPLOYMENT", years=10)
112-
113-
# Nordic + Germany comparison — top 3 domain indicators, 5-year series
114-
for country in [DK, NO, FI, DE]:
115-
get-economic-data(countryCode=country, indicator=<top-3>, years=5)
116-
117-
# Domain-specific extras (only when article touches the domain)
118-
get-health-data(countryCode="SE", indicator="HEALTH_EXPENDITURE", years=5)
119-
get-education-data(countryCode="SE", indicator="EDUCATION_EXPENDITURE", years=5)
120-
get-social-data(countryCode="SE", indicator="POPULATION", years=10)
156+
```bash
157+
# 1. WEO time series for one country (default 10 years; --persist caches
158+
# the JSON under analysis/data/imf/{indicator}/{country}.json with
159+
# projectionVintage provenance).
160+
tsx scripts/imf-fetch.ts weo \
161+
--country SWE --indicator NGDP_RPCH --years 15 --persist
162+
163+
# 2. Compare the latest WEO value across Sweden + Nordic peers in one call.
164+
tsx scripts/imf-fetch.ts compare \
165+
--indicator GGXWDG_NGDP \
166+
--countries SWE,DNK,NOR,FIN,DEU --persist
167+
168+
# 3. SDMX 3.0 passthrough for IFS / BOP / FM / GFS / DOTS.
169+
tsx scripts/imf-fetch.ts sdmx \
170+
--path "/data/IMF.STA,CPI,4.0.0/M.SE.PCPI_IX?startPeriod=2024-01" \
171+
--indicator PCPI_IX --country SWE --persist
172+
173+
# 4. Inspect the built-in WEO + FM indicator catalog (no network call).
174+
tsx scripts/imf-fetch.ts list-indicators
121175
```
122176

123-
Committee → minimum indicator mapping (shortened — full matrix in the
124-
inventory JSON):
177+
**Rate-limit discipline** (IMF ~10 req / 5 s): prefer the `compare`
178+
subcommand (one batched call across countries), insert a 1 s sleep
179+
between separate `imf-fetch.ts` invocations, and rely on the client's
180+
built-in 3× retry with exponential back-off (1 s → 2 s → 4 s) for 429 /
181+
5xx. Pre-warm 1 request at workflow start.
125182

126-
| Committee | MUST query |
127-
|-----------|-----------------------------------------------------------------|
128-
| FiU | GDP_GROWTH, INFLATION, GDP_PER_CAPITA, GOVERNMENT_DEBT |
129-
| AU | UNEMPLOYMENT, LABOR_FORCE, YOUTH_UNEMPLOYMENT |
130-
| SkU | TAX_REVENUE, GDP_GROWTH |
131-
| SoU | HEALTH_EXPENDITURE, PHYSICIANS, HOSPITAL_BEDS, LIFE_EXPECTANCY |
132-
| UbU | EDUCATION_EXPENDITURE, LITERACY_RATE, SCHOOL_ENROLLMENT |
133-
| FöU | MILITARY_EXPENDITURE, MILITARY_EXPENDITURE_GDP |
134-
| MJU | CO2_EMISSIONS, RENEWABLE_ENERGY, FOREST_AREA |
135-
| JuU | HOMICIDE_RATE, PRISON_POPULATION |
136-
| CU | HOUSING_EXPENDITURE, MORTGAGE_RATE |
137-
| TU | TRANSPORT_INFRASTRUCTURE_SPENDING |
183+
### 3. Query World Bank (governance / env / social residue)
184+
185+
```
186+
# Kept for indicators IMF does not cover
187+
get-economic-data(countryCode="SE", indicator="CC.EST", years=5) # Control of Corruption (WGI, source=75)
188+
get-economic-data(countryCode="SE", indicator="EN.ATM.CO2E.PC", years=10) # CO2 emissions
189+
get-social-data(countryCode="SE", indicator="POPULATION", years=10)
190+
```
138191

139-
### 3. Query SCB (Statistics Sweden)
192+
### 4. Query SCB (Statistics Sweden)
140193

141194
```
142195
# CRITICAL: language MUST be "sv" or "en". NEVER "no" — SCB returns
@@ -150,7 +203,22 @@ search_tables(query="<committee-topic>", language="en")
150203
query_table(table_id="<TAB>", value_codes={"Tid": "top(10)", ...})
151204
```
152205

153-
### 4. (High-level reviews only) D3 coalition-flow dataset
206+
### Committee → primary provider & indicator matrix (v2)
207+
208+
| Committee | Primary provider(s) | MUST query (provider:code) |
209+
|-----------|---------------------|-----------------------------------------------------------------------------------------------|
210+
| FiU | IMF + WB | `imf:WEO:NGDP_RPCH`, `imf:WEO:PCPIPCH`, `imf:WEO:NGDPDPC`, `imf:WEO:GGXWDG_NGDP` |
211+
| SkU | IMF + WB | `imf:WEO:GGR_NGDP`, `imf:WEO:GGX_NGDP`, `imf:WEO:GGXCNL_NGDP`, `imf:FM:GGXONLB_NGDP` |
212+
| AU | IMF + WB | `imf:WEO:LUR`, `wb:SL.UEM.1524.ZS`, `wb:SL.TLF.CACT.ZS` |
213+
| NU / UU | IMF | `imf:WEO:BCA_NGDPD`, `imf:WEO:TX_RPCH` |
214+
| SoU | WB | `wb:SH.XPD.CHEX.GD.ZS`, `wb:SH.MED.PHYS.ZS`, `wb:SH.MED.BEDS.ZS`, `wb:SP.DYN.LE00.IN` |
215+
| UbU | WB | `wb:SE.XPD.TOTL.GD.ZS`, `wb:SE.ADT.LITR.ZS`, `wb:SE.PRM.ENRR` |
216+
| FöU | WB | `wb:MS.MIL.XPND.GD.ZS`, `wb:MS.MIL.XPND.CD` |
217+
| MJU | WB | `wb:EN.ATM.CO2E.PC`, `wb:EG.FEC.RNEW.ZS`, `wb:AG.LND.FRST.ZS` |
218+
| KU | WB | `wb:CC.EST`, `wb:RL.EST`, `wb:VA.EST` (WGI, source=75) |
219+
| JuU | WB | `wb:VC.IHR.PSRC.P5`, `wb:CC.EST` |
220+
221+
### 5. (High-level reviews only) D3 coalition-flow dataset
154222

155223
Article types: `week-ahead`, `month-ahead`, `weekly-review`,
156224
`monthly-review`. In addition to `economic-data.json`, produce a
@@ -236,9 +304,12 @@ cat > "$ANALYSIS_DIR/economic-data.json" <<EOF
236304
EOF
237305
```
238306

239-
Cache raw MCP responses under
240-
`analysis/data/worldbank/$(date +%Y)/$indicator-$country.json` so
241-
subsequent article types in the same daily run reuse data (rate-limit
307+
Cache raw MCP responses alongside the legacy WB path:
308+
- IMF: `analysis/data/imf/$(date +%Y)/$indicator-$country.json`
309+
- World Bank: `analysis/data/worldbank/$(date +%Y)/$indicator-$country.json`
310+
- SCB: `analysis/data/scb/$(date +%Y)/$table.json`
311+
312+
Reuse across article types in the same daily run (rate-limit
242313
mitigation).
243314

244315
---
@@ -259,6 +330,22 @@ Banned phrasings (all detected by `multi-dim quality score`):
259330
- "Touches on X policy…"
260331
- "Analysis of N documents…"
261332
- Pure definitions of indicators (e.g. "GDP is the total output of…").
333+
- Un-sourced forecasts — phrases like "Sweden will…" / "The economy is
334+
expected to…" without a cited IMF WEO or Fiscal Monitor value from
335+
`dataPoints` where `projection: true`. Use the explicit form "IMF
336+
projects Sweden's debt/GDP at 32.4 % in 2027 (WEO Apr-2026,
337+
GGXWDG_NGDP)" instead.
338+
339+
### Projections — allowed usage
340+
341+
From schema v2 onwards, `dataPoint.projection === true` values may be
342+
cited in commentary **only** for these article types:
343+
344+
- `week-ahead`, `month-ahead` — explicit forward-looking narrative
345+
- `weekly-review`, `monthly-review` — retrospective + 6-12 month outlook
346+
347+
Any projection citation MUST include the `projectionVintage` tag
348+
(e.g. `(WEO-2026-04)`) to make stale vintages visible to the audit.
262349

263350
---
264351

@@ -274,7 +361,9 @@ commits violations:
274361
3. Missing / empty / malformed `economic-data.json`.
275362
4. `dataPoints` empty (without a valid `skip: true`).
276363
5. Commentary below `minCommentaryWords`.
277-
6. Missing footer attribution "Data by World Bank / SCB".
364+
6. Missing footer attribution "Data by IMF / World Bank / SCB"
365+
(historical variants "Data by World Bank / SCB" still accepted
366+
during the v1→v2 grace window).
278367

279368
### Contract effective date
280369

@@ -313,3 +402,23 @@ mirror the change in the version history below.
313402
exemption to the validator so the daily audit stops re-reporting
314403
pre-contract articles for 7 days after every rollout. No change to
315404
the schema or enforcement for new articles.
405+
- **2.0 (2026-04-20)** — Add IMF as a first-class primary source via
406+
the repository's pure-TypeScript `scripts/imf-client.ts` +
407+
`scripts/imf-fetch.ts` CLI (Datamapper JSON for WEO, SDMX 3.0
408+
passthrough for IFS / BOP / FM / GFS / DOTS). **No Python MCP /
409+
`uvx`** — IMF access is under the same npm / SBOM governance as
410+
`world-bank-client.ts` and `scb-client.ts`. Additive schema changes:
411+
- `source.imf: string[]` (optional in v1, recommended in v2)
412+
- `dataPoints[].provider` (`imf` | `worldBank` | `scb`)
413+
- `dataPoints[].projection` (boolean)
414+
- `dataPoints[].projectionVintage` (string; required when
415+
`projection: true`)
416+
Validator now accepts IMF in the footer attribution and treats any
417+
non-empty `source.{imf,worldBank,scb}` as satisfying citation.
418+
Projections are allowed in commentary for look-ahead article types
419+
(`week-ahead`, `month-ahead`, `weekly-review`, `monthly-review`)
420+
only, and MUST carry the `projectionVintage` tag. Un-sourced
421+
forecast phrasing added to the banned list. World Bank remains
422+
authoritative for WGI governance, environment, and long-horizon
423+
social/education residue; SCB unchanged. v1 artefacts remain valid
424+
through the 2026-04-20 → 2026-05-31 grace window.

0 commit comments

Comments
 (0)