Skip to content

CI: gate on model correctness; make vendor-reference actually run - #2

Merged
vahid-ahmadi merged 1 commit into
mainfrom
ci-correctness-gates
Jul 19, 2026
Merged

CI: gate on model correctness; make vendor-reference actually run#2
vahid-ahmadi merged 1 commit into
mainfrom
ci-correctness-gates

Conversation

@vahid-ahmadi

Copy link
Copy Markdown
Contributor

What CI covered before

  • One test job: ruff + a bare pytest -q on Python 3.10/3.12. The tracking and cross-validation invariants existed as tests but were not called out or gated independently.
  • A vendor-reference job that was if: github.event_name == 'workflow_dispatch' and continue-on-error: true — on run 29654867764 it shows as skipped. The reference-CSV path had effectively zero CI coverage and could not fail a build.
  • No scheduled revalidation.

What this adds

correctness-gates job — hard-failing, one step per invariant so a red build names what broke:

  • tracking invariant: baseline reproduces LONGBASE to < 1e-8 abs / < 1e-10 rel
  • cross-validation vs the committed pyfrbus reference: < 1e-6 abs and rel
  • monetary IRF economic sanity

vendor-reference job — now runs on every push/PR, no continue-on-error. It:

  1. regenerates the reference by actually running the Fed's pyfrbus from vendor/pyfrbus_package (patched copy, throwaway py3.11 venv),
  2. gates this implementation against that freshly generated vendor solution (new test_cross_validation_vs_freshly_generated_vendor, < 1e-6) — so the gate exercises vendor code, not a possibly-stale CSV,
  3. runs new scripts/check_reference_drift.py to confirm the committed anchor still matches the vendor package,
  4. fails if tests/data/ was modified in place. generate_vendor_reference.sh now takes an optional output path so CI never rewrites the committed anchor. Runtime ~1 min.

scheduled-validation job — weekly (Mondays 05:17 UTC) + on demand: full suite on Python 3.10/3.11/3.12 plus the vendor regeneration gate, to catch transitive-dependency drift without a PR.

Economic-sanity test (test_monetary_irf_economic_sanity, was test_sanity_signs) — explicit sign assertions, magnitude bands, plus new assertions that the output trough is lagged (quarters 3–15, not on impact) and that output never rises above baseline. The band and its source are documented in the docstring: Brayton, Laubach & Reifschneider, The FRB/US Model: A Tool for Macroeconomic Policy Analysis (FEDS Notes, 2014), and the FRB/US package documentation in vendor/frbus_package/documentation/. Bands are deliberately wider than observed values so this gates on economics, not bit-level reproduction.

Genuine failures discovered

None. All gates pass locally, including a real vendor regeneration: the freshly generated vendor solution matches the committed reference at 8.2e-9 abs / 3.0e-8 rel (worst variable wpsn), consistent with the solver-tolerance noise floor documented in VALIDATION.md Test 2b. No tolerance was loosened and no test was skipped.

🤖 Generated with Claude Code

…ally run

The vendor-reference job was `if: workflow_dispatch` + `continue-on-error`,
so the reference-CSV-based check never ran and could not fail a build. The
correctness invariants were only implicitly covered by a bare `pytest -q`.

- Add a `correctness-gates` job running the tracking invariant (< 1e-8),
  cross-validation vs the committed pyfrbus reference (< 1e-6), and the
  monetary-IRF sanity test as separate, hard-failing steps.
- Make `vendor-reference` run on every push/PR without continue-on-error. It
  now regenerates the reference by actually executing the Fed's pyfrbus from
  vendor/, gates this implementation against that FRESH solution, and checks
  the committed anchor has not drifted from the vendor package via the new
  scripts/check_reference_drift.py. It writes to a scratch path and fails if
  tests/data/ is modified in place.
- Add a weekly `scheduled-validation` job: full suite on Python 3.10-3.12
  plus the vendor regeneration gate.
- Strengthen the monetary IRF test into an economic-sanity test with explicit
  sign assertions, a trough-timing assertion, and magnitude bands sourced to
  Brayton/Laubach/Reifschneider (FEDS Notes 2014) and the FRB/US package
  documentation, documented in the test docstring.
- Document the CI gating table in VALIDATION.md.

No tolerance was loosened; all gates pass locally, including a real vendor
regeneration (committed reference matches at 8.2e-9 abs / 3.0e-8 rel).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vahid-ahmadi
vahid-ahmadi merged commit a25b9df into main Jul 19, 2026
5 checks passed
@vahid-ahmadi
vahid-ahmadi deleted the ci-correctness-gates branch July 19, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant