Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [
["@mostlyrightmd/core", "@mostlyrightmd/weather", "@mostlyrightmd/markets", "mostlyright"]
["@mostlyrightmd/core", "@mostlyrightmd/weather", "@mostlyrightmd/markets", "@mostlyrightmd/econ", "mostlyright"]
],
"linked": [],
"access": "public",
Expand Down
17 changes: 14 additions & 3 deletions .github/workflows/release-ts.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
name: Release (npm OIDC trusted publishing)

# TS-W7 TS-RELEASE-01 — publish the four TS packages to npm on every vts-* tag.
# TS-W7 TS-RELEASE-01 — publish the five TS packages to npm on every vts-* tag.
#
# Trusted publishing via OIDC (no NPM_TOKEN in secrets); requires
# `id-token: write` permission. Setup checklist before the first tagged
# release (operator-gated, mirrors Python release.yml playbook):
#
# 1. On npmjs.com, register each scoped package as a "pending publisher":
# @mostlyrightmd/core, @mostlyrightmd/weather, @mostlyrightmd/markets, mostlyright
# pointed at repo helloiamvu/tradewinds, workflow filename
# @mostlyrightmd/core, @mostlyrightmd/weather, @mostlyrightmd/markets,
# @mostlyrightmd/econ, mostlyright
# pointed at repo mostlyrightmd/mostlyright-sdk, workflow filename
# `release-ts.yml`, environment name `npm`.
# https://docs.npmjs.com/generating-provenance-statements
# 2. If the `@mostlyright` npm scope is unavailable, fall back per
Expand Down Expand Up @@ -157,6 +158,16 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}

- name: Publish — @mostlyrightmd/econ
working-directory: packages-ts/econ
# pnpm publish (NOT npm publish): econ's @mostlyrightmd/core
# peerDependency is rewritten from the ^0.0.0 placeholder to ^<version>
# by the preflight above; pnpm also handles any workspace protocol at
# pack time. Mirrors the weather/markets scoped-package publish path.
run: pnpm publish --access public --tag ${{ steps.dist_tag.outputs.tag }} --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}

- name: Publish — mostlyright (meta)
working-directory: packages-ts/meta
# Use `pnpm publish` (NOT `npm publish`) because the meta package
Expand Down
44 changes: 36 additions & 8 deletions .github/workflows/test-ts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ name: Test (TypeScript)
# TS-W0 / TS-CI-01 — TypeScript fast suite.
# Pipeline: pnpm install -> codegen -> typecheck -> biome -> vitest -> size-limit.
#
# Shape: a `test-ts-matrix` job does the work, fanning out over Node 20 + 22
# (engines.node is ">=20"), and a separate `test-ts` job aggregates the matrix
# result to stay the single stable REQUIRED status check on `main`.
#
# `test-ts` is a REQUIRED status check on `main`. A path-filtered required check
# never reports for PRs that don't touch its paths, which leaves such PRs stuck
# on "Expected — waiting for status" and unmergeable (e.g. a Python-only
# external fork PR). So on `pull_request` this job runs UNCONDITIONALLY and
# detects TS-relevant changes inside the job: when none changed, the heavy
# steps are skipped and the job still reports success — preserving the original
# "don't burn CI minutes when only Python source moves" intent while always
# emitting the required `test-ts` context. The `push` trigger stays
# path-filtered (off-PR pushes are not gated by required checks).
# external fork PR). So on `pull_request` the matrix legs run UNCONDITIONALLY and
# detect TS-relevant changes inside the job: when none changed, the heavy
# steps are skipped and each leg still reports success — preserving the original
# "don't burn CI minutes when only Python source moves" intent. The matrix legs
# surface as non-required contexts `test-ts-matrix (20)` / `test-ts-matrix (22)`;
# the `test-ts` gate job (needs: [test-ts-matrix], if: always()) fails unless
# every leg succeeded, so the required `test-ts` context is preserved unchanged
# and branch protection needs no edit when the Node matrix grows. The `push`
# trigger stays path-filtered (off-PR pushes are not gated by required checks).

on:
push:
Expand All @@ -26,8 +33,12 @@ on:
pull_request: {}

jobs:
test-ts:
test-ts-matrix:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: ["20", "22"]
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -62,7 +73,7 @@ jobs:
if: steps.changes.outputs.ts == 'true'
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: ${{ matrix.node-version }}
cache: pnpm

- name: Install dependencies
Expand Down Expand Up @@ -107,3 +118,20 @@ jobs:
if: steps.changes.outputs.ts == 'true'
run: pnpm -r run size-limit
continue-on-error: true

# Stable required-check context. `test-ts-matrix` fans out over Node 20 + 22;
# this job aggregates their result so `test-ts` remains the single required
# status on `main` (branch protection needs no change). Fails if any matrix
# leg failed or was cancelled.
test-ts:
needs: [test-ts-matrix]
runs-on: ubuntu-latest
if: always()
steps:
- name: Gate on matrix result
run: |
if [ "${{ needs.test-ts-matrix.result }}" != "success" ]; then
echo "test-ts-matrix result: ${{ needs.test-ts-matrix.result }} — failing the required check."
exit 1
fi
echo "test-ts-matrix succeeded on all Node versions."
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to `mostlyright`. The format follows [Keep a Changelog](http

## [Unreleased]

## [1.16.0] — 2026-07-14 — Economic indicators vertical: first published `mostlyrightmd-econ` / `@mostlyrightmd/econ` dist

First release of the **econ vertical** — CPI, PPI, nonfarm payrolls, unemployment,
GDP, jobless claims, and Fed decisions for Kalshi + Polymarket — as the 4th
published PyPI dist (`mostlyrightmd-econ`) and 5th npm package
(`@mostlyrightmd/econ`), in lockstep with core/weather/markets/meta at 1.16.0.
(`1.15.0` shipped the general-first re-layering without econ, so econ debuts here.)

### Added

- **Econ surface conformance to the 1.13/1.14 source-identity contract
Expand All @@ -27,6 +35,14 @@ All notable changes to `mostlyright`. The format follows [Keep a Changelog](http
`dataset()`/`research()` are **not** modified (an `include_econ` covariate seam
is an option-B question deferred to review); the econ↔weather firewall
(`test_firewall.py`) stays green.
- **Packaging / release.** All published TS packages now declare
`engines.node >= 20` (matching the workspace root); the `test-ts` CI runs on
Node 20 **and** 22 via a matrix behind a stable required-check gate; and the
npm release path (`release-ts.yml`, `release-ts-preflight.mjs`, the changesets
`fixed` group) is wired for `@mostlyrightmd/econ` so it publishes to npm in
lockstep (PyPI was already wired in 29-01). Data-source licensing notices
completed: the FRED®/BEA required disclaimers plus the BLS "cannot vouch"
citation string; the BLS API ToS was verified permissive (no end-use controls).

## [1.15.0] — 2026-07-10 — General-first re-layering: the label axis, thin markets delegators, panels, and the contributor registry

Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ This applies to every PLAN.md generated by `/gsd-plan-phase`, every PROJECT.md "
- **Cache:** `$HOME/.mostlyright/cache/observations/{station}/{year}/{month}.parquet`. `filelock`-guarded. Cache-skip when queried month equals current LST month for that station (current month is incomplete; elapsed months stable). No user-visible `fresh=` kwarg.
- **No preprocessing in v0.1.0.** Preserve `raw_metar` in observation rows so MetPy re-parse works (Vojtech's documented workflow). RH/feels_like preprocessing comes in Sprint 0.5+.
- **Raw + preprocessed split:** quants want both. Default fetch returns raw; preprocessing is opt-in via explicit transform calls (Sprint 0.5+).
- **Data licensing:** Any change that adds/changes a data source, a fetcher, or cache persistence MUST consult [`.planning/research/DATA-LICENSING.md`](.planning/research/DATA-LICENSING.md). Per-source posture: **BLS / BEA / Fed Board = public domain** (US-gov works, 17 U.S.C. §105 — free to cache, train on, redistribute); **FRED / ALFRED = contract ToU** that bans ML/training use + store/cache/archive + restricts commercial use (St. Louis Fed is a Reserve Bank, not a federal agency). The **published default path calls agency sources directly** (public-domain) and makes NO FRED call; FRED is BYO-key opt-in (the user's own ToU acceptance) and FRED-derived rows are never persisted by default (`MOSTLYRIGHT_PERSIST_FRED=1` to opt in). Phase plans that add/change a source require a **"Data licensing"** section — same presence-check enforcement as the Dual-SDK "TS Parity" rule. (D-LIC-4)

## CWOP adapter (`mostlyright.weather.cwop`)

Expand Down
8 changes: 6 additions & 2 deletions docs/econ-vertical.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,15 @@ certified by the Federal Reserve Bank of St. Louis. This product uses the
Bureau of Economic Analysis (BEA) Data API but is not endorsed or certified by
BEA. Nothing in this package is endorsed by, or implies endorsement by, any
source agency or Reserve Bank. Please cite the source agencies when you
publish results derived from their data.
publish results derived from their data. Per the
[BLS Terms of Service](https://www.bls.gov/developers/termsOfService.htm), BLS
data additionally requires citing the retrieval date and stating: "BLS.gov
cannot vouch for the data or analyses derived from these data after the data
have been retrieved from BLS.gov."

| Source | Legal basis | Cache/persist | ML/training | Notes |
|---|---|---|---|---|
| BLS, BEA, DOL, Fed **Board** | US-gov works → public domain (17 U.S.C. §105) | Yes | Yes | Citation appreciated. BEA API rate limits: 100 req/min, 100 MB/min. |
| BLS, BEA, DOL, Fed **Board** | US-gov works → public domain (17 U.S.C. §105) | Yes | Yes | BLS ToS (read 2026-07-14): no end-use controls, but cite the retrieval date + the "BLS.gov cannot vouch…" disclaimer, no BLS logo. BEA API rate limits: 100 req/min, 100 MB/min. |
| FRED / ALFRED (`alfred` rows) | Contract — [FRED® ToU](https://fred.stlouisfed.org/docs/api/terms_of_use.html) | **Prohibited by ToU** | **Prohibited by ToU** | Opt-in via your `FRED_API_KEY`; the keyless default path makes no FRED call. |
| Jobless claims (`dol.icsa` rows) | DOL data is public domain, **but the bytes are fetched from FRED** (`ICSA`/`ICNSA` — DOL's machine path is bot-walled) | FRED ToU applies | FRED ToU applies | Same posture as `alfred` rows. |
| Trading Economics | Proprietary — cannot license | n/a (never fetched) | n/a | The 48 TE-settled series ship the agency first print labeled `settlement_grade=False` (limitation 3). |
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"scripts": {
"codegen": "pnpm -r run codegen",
"build": "pnpm --filter @mostlyrightmd/core run build && pnpm --filter @mostlyrightmd/weather run build && pnpm --filter @mostlyrightmd/markets run build && pnpm --filter mostlyright run build",
"build": "pnpm --filter @mostlyrightmd/core run build && pnpm --filter @mostlyrightmd/weather run build && pnpm --filter @mostlyrightmd/markets run build && pnpm --filter @mostlyrightmd/econ run build && pnpm --filter mostlyright run build",
"test": "pnpm -r run test",
"lint": "biome check .",
"format": "biome format --write .",
Expand All @@ -44,6 +44,11 @@
"path": "packages-ts/markets/dist/index.mjs",
"limit": "15 KB"
},
{
"name": "@mostlyrightmd/econ (econ vertical surface, gzipped ESM)",
"path": "packages-ts/econ/dist/index.mjs",
"limit": "18 KB"
},
{
"name": "mostlyright meta (W1 subset + 32-05 label axis, gzipped ESM)",
"path": "packages-ts/meta/dist/index.mjs",
Expand Down
5 changes: 4 additions & 1 deletion packages-ts/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mostlyrightmd/core",
"version": "1.15.0",
"version": "1.16.0",
"description": "TypeScript SDK core for quants, ML pipelines, and AI agents: types, schemas, validators, temporal-safety primitives, and the research() join over weather data + prediction-market settlements. Local-first, no hosted backend.",
"keywords": [
"weather",
Expand Down Expand Up @@ -31,6 +31,9 @@
"url": "https://github.com/mostlyrightmd/mostlyright-sdk/issues"
},
"type": "module",
"engines": {
"node": ">=20"
},
"sideEffects": false,
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
Expand Down
5 changes: 4 additions & 1 deletion packages-ts/econ/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mostlyrightmd/econ",
"version": "1.15.0",
"version": "1.16.0",
"description": "Economic-indicator data for TypeScript / Node — CPI, PPI, nonfarm payrolls (NFP), U3 unemployment, initial jobless claims, GDP, and Fed decisions, joined to Kalshi + Polymarket econ markets for leakage-free settlement pairs. First-print / ALFRED vintage discipline. Direct public-API access, no hosted backend.",
"keywords": [
"economic-indicators",
Expand Down Expand Up @@ -38,6 +38,9 @@
"url": "https://github.com/mostlyrightmd/mostlyright-sdk/issues"
},
"type": "module",
"engines": {
"node": ">=20"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
Expand Down
5 changes: 4 additions & 1 deletion packages-ts/markets/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mostlyrightmd/markets",
"version": "1.15.0",
"version": "1.16.0",
"description": "Prediction-market data for TypeScript / Node — Kalshi NHIGH/NLOW weather-contract resolvers, Polymarket discovery + settlement, and Kalshi + Polymarket trade history. For quants, backtesting, and ML training pipelines.",
"keywords": [
"kalshi",
Expand Down Expand Up @@ -31,6 +31,9 @@
"url": "https://github.com/mostlyrightmd/mostlyright-sdk/issues"
},
"type": "module",
"engines": {
"node": ">=20"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
Expand Down
5 changes: 4 additions & 1 deletion packages-ts/meta/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mostlyright",
"version": "1.15.0",
"version": "1.16.0",
"description": "Public-data SDK for TypeScript — one import for quants, ML pipelines, and AI agents. Adapters ship weather (METAR, ASOS, GHCNh, NWS CLI) and prediction-market settlements (Kalshi NHIGH/NLOW, Polymarket) today; SEC filings, Federal Reserve series, court filings, FDA approvals, and equities are next. Local-first, no hosted backend.",
"keywords": [
"weather",
Expand Down Expand Up @@ -35,6 +35,9 @@
"url": "https://github.com/mostlyrightmd/mostlyright-sdk/issues"
},
"type": "module",
"engines": {
"node": ">=20"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
Expand Down
5 changes: 4 additions & 1 deletion packages-ts/weather/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mostlyrightmd/weather",
"version": "1.15.0",
"version": "1.16.0",
"description": "Weather data for TypeScript / Node — live METAR (AWC), ASOS archive (IEM), historical observations (GHCNh), and NWS climate text products (CLI). For quants, ML training pipelines, and weather-bot agents. Direct public-API access, no hosted backend.",
"keywords": [
"weather",
Expand Down Expand Up @@ -35,6 +35,9 @@
"url": "https://github.com/mostlyrightmd/mostlyright-sdk/issues"
},
"type": "module",
"engines": {
"node": ">=20"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mostlyrightmd"
version = "1.15.0"
version = "1.16.0"
description = "Python SDK for quants, ML engineers, and AI agents — one interface to public data. Adapters ship weather + prediction-market settlements (Kalshi NHIGH/NLOW, Polymarket) today; SEC filings, Federal Reserve series, court filings, FDA approvals, and equities are next. Schema-versioned, leakage-free, local-first. Imports as `mostlyright`."
readme = "README.md"
license = "MIT"
Expand Down
6 changes: 5 additions & 1 deletion packages/econ/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ This product uses the FRED® API but is not endorsed or certified by the Federal
Reserve Bank of St. Louis. This product uses the Bureau of Economic Analysis
(BEA) Data API but is not endorsed or certified by BEA. BLS, BEA, DOL, and
Federal Reserve Board data are US-government works in the public domain;
citations to the source agencies are appreciated. Nothing in this package is
citations to the source agencies are appreciated. Per the
[BLS Terms of Service](https://www.bls.gov/developers/termsOfService.htm), when
you publish results derived from BLS data retrieved via this SDK, cite the
retrieval date and state: "BLS.gov cannot vouch for the data or analyses derived
from these data after the data have been retrieved from BLS.gov." Nothing in this package is
endorsed by, or implies endorsement by, any source agency or Reserve Bank.

The **keyless default path makes no FRED call**. The FRED/ALFRED vintage path is
Expand Down
2 changes: 1 addition & 1 deletion packages/econ/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mostlyrightmd-econ"
version = "1.15.0"
version = "1.16.0"
description = "Economic-indicator data for Python — CPI, PPI, nonfarm payrolls, unemployment, GDP, jobless claims, Fed decisions — from FRED/ALFRED, BLS, BEA, DOL, Federal Reserve. First-print vintage discipline for prediction-market settlement. Imports as `mostlyright.econ`."
readme = "README.md"
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion packages/markets/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mostlyrightmd-markets"
version = "1.15.0"
version = "1.16.0"
description = "Prediction-market data for Python — Kalshi NHIGH/NLOW weather-contract resolvers, Polymarket discovery + settlement, and Kalshi + Polymarket trade history. For quants, backtesting, and ML training pipelines. Imports as `mostlyright.markets`."
readme = "README.md"
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion packages/weather/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mostlyrightmd-weather"
version = "1.15.0"
version = "1.16.0"
description = "Weather data for Python — live METAR (AWC), ASOS archive (IEM), historical observations (GHCNh), and NWS climate text products (CLI). For quants, ML training pipelines, and weather-bot agents. Direct public-API access, no hosted backend. Imports as `mostlyright.weather`."
readme = "README.md"
license = "MIT"
Expand Down
5 changes: 3 additions & 2 deletions scripts/release-ts-preflight.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node
// TS-W7 — release-ts.yml preflight.
//
// Normalizes the pushed tag and asserts the four package.json versions match
// Normalizes the pushed tag and asserts the five package.json versions match
// the expected version before any `pnpm publish` runs. Also rewrites the
// inter-package peerDependencies range so the published packages declare
// the correct cross-pin (pnpm only rewrites `workspace:*`, NOT plain
Expand All @@ -19,6 +19,7 @@ const PACKAGES = [
"packages-ts/core",
"packages-ts/weather",
"packages-ts/markets",
"packages-ts/econ",
"packages-ts/meta",
];

Expand Down Expand Up @@ -80,7 +81,7 @@ async function main() {
// plain peerDependencies untouched (codex iter-5 P1; Phase 12 rename
// moved the key from @tradewinds/core to @mostlyrightmd/core).
const PEER_KEY = "@mostlyrightmd/core";
for (const pkg of ["packages-ts/weather", "packages-ts/markets"]) {
for (const pkg of ["packages-ts/weather", "packages-ts/markets", "packages-ts/econ"]) {
const path = resolve(ROOT, pkg, "package.json");
const pj = await readJson(path);
if (pj.peerDependencies?.[PEER_KEY] === undefined) {
Expand Down
8 changes: 4 additions & 4 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading