Skip to content

lecture-wasm dynamic snapshots: business_cycle reads the four data-lectures snapshots (P4) #118

Open
2 of 4 issues completed

Description

@mmcky

This issue is the tracker for the wasm-dynamic-snapshots project in the status-projects registry (programme: infrastructure; project page), and its sub-issues are the work list. The project moves lecture-wasm's business_cycle lecture off its live World Bank and FRED calls and onto the four business_cycle dynamic snapshots this repo serves, so the lecture runs in the reader's browser from a cached copy that refreshes by pull request. Done means three things: the lecture is re-enabled in lecture-wasm and runs end to end in the browser; the four snapshots record it as their consumer and are marked repointed; and the P4 box in PLAN.md Phase 8 is ticked. The work began on 2026-09-01 as Track E of the datasets migration (project page). On 2026-09-29 @mmcky ruled it a project of its own, with this issue as its tracker, so that the migration can close without it.

Where we stand (verified 2026-09-30)

The four snapshots landed on 2026-09-01: gdp_growth_annual.csv (as business_cycle_data.csv in #109), then unemployment_rate_annual.csv, private_credit_to_gdp.csv and us_business_cycle_monthly.csv (#114). The weekly canary and refresh-as-PR workflow landed the same day (#110), with its first refresh (#112) and its first real alarm, a FRED fetch timeout it classified correctly (#115). On 2026-09-07 block A settled the names (#113, landed in #124), so the four filenames are final, and the shared manifest-driven validate() began checking all four on every PR (#126). On 2026-09-30 the canary proof closed (#147). Two dispatched runs showed a validation failure exiting 2 and notify opening an upstream-break issue, then commenting on it. In the second run the file was due and the refresh job was still skipped. No lecture reads the files yet. The same day @mmcky took decisions 1 and 2 and ruled on FRED's caching clause (see "Decisions taken"), and blocks B and C opened as draft PRs, QuantEcon/lecture-wasm#85 and #153. Two data-lectures PRs went first and merged the same day: #151, an audit annotation that main needed regardless (intro's mle began reading yfinance on 2026-09-29), and #152, which records the licence decisions. Next the first monthly refresh merges, B's gate runs on its preview, and B and C merge on the same day.

Fact State on 2026-09-30
The four snapshots each serves HTTP 200 from raw.githubusercontent.com with access-control-allow-origin: * and bytes matching its manifest's sha256; all four retrieved 2026-09-01
Their consumers none: every manifest has consumers: [], migration.yml holds them at landed, and the audit of 2026-09-28 finds no reader
Refresh workflow refresh-snapshots green on every scheduled run since 2026-09-07, the last on 2026-09-28. The two failed runs on 2026-09-30 are #147's probe, failing by design. Nothing is due before 2026-10-01
lecture-wasm lectures/business_cycle.md unchanged since 2025-10-23 (QuantEcon/lecture-wasm#31) and still commented out of lectures/myst.yml, so the page 404s on the live site; block B open as QuantEcon/lecture-wasm#85 (draft); main at ff9196d
lecture-wasm previews Netlify's app check fails on every PR (QuantEcon/lecture-wasm#62), while the workflow's own preview at pr-<N>--beautiful-dodol-cb9543.netlify.app serves real pages
data-lectures main at bbb4cc6 after #151 and #152, with its audit green and deployed; the audit of 2026-09-28 counted 23 lectures that call live APIs, 5 of them in lecture-wasm

The work

Each block is a sub-issue. This table says what each one is for; the sub-issue list carries its state.

Block Sub-issue Delivers Gate
A. Naming #113 the naming policy; the four filenames final (landed in #124, 2026-09-07) done
B. lecture-wasm adoption QuantEcon/lecture-wasm#70, PR QuantEcon/lecture-wasm#85 business_cycle.md reads the four files and is re-enabled in lectures/myst.yml; the lecture runs end to end in the browser on the PR's own preview the first monthly refresh merged (#152 merged 2026-09-30), then Run all on the preview
C. The flip #146, PR #153 lecture-wasm recorded as the consumer on all four manifests, migration.yml at repointed, CATALOG.md regenerated, the strict audit dry-run in both directions B merged; same day
Canary proof #147 the weekly canary shown catching an induced validation failure (exit 2), the last item on P4's line in PLAN.md and one of QuantEcon/meta#338's success criteria done 2026-09-30

B is larger than QuantEcon/lecture-wasm#70 records (measured 2026-09-29):

B and C land on the same day. Between B's merge and C's merge this repo's strict audit fails, because a landed record has a reader. Every push to main, the Monday 05:17 UTC run and any PR that touches a manifest go red, including the monthly refresh PR, and the Pages deploy is skipped. Avoid a Monday.

Deadlines

When What
2026-10-01 us_business_cycle_monthly.csv falls due: monthly cadence, 30 days after retrieved 2026-09-01
Monday 2026-10-05, about 06:17 UTC the first scheduled monthly refresh PR should open on refresh/us_business_cycle_monthly. This is projected from refresh-snapshots.yml and has not been observed yet; scheduled runs have started 30 to 40 minutes late
2026-10-31 the last day to merge that refresh. The committed file's newest month is 2026-07, which from 2026-11-01 is more than MAX_STALENESS_MONTHS = 3 old. From then check_committed() in builders/business_cycle_fred.py fails validate-datasets on every PR and every push to main. It is not a required check, so merges still go through. Each merge restarts the clock, so merging the refresh every month is a standing duty that outlives this project
2027-09-01 the three World Bank files fall due (annual cadence); their builder's staleness guard holds until 2028-01-01

Decisions taken

Decisions open

  1. on_refresh for lecture-wasm, set in C. Flip wave P4 to repointed — the four business_cycle snapshots #153 sets rebuild, because no prose in B quotes a number a refresh can move. It is taken when C merges, unless B's prose changes in review.
  2. Who merges the monthly FRED refresh PRs once this project closes.

Not in scope

Learned along the way: kept from the session plan of 2026-09-01, with facts added on 2026-09-07, 2026-09-29 and 2026-09-30
  • FRED stalls custom user agents from GitHub-hosted runners (qeld-builder, and even Mozilla/5.0), but it answers urllib's default user agent and curl in about 50 ms. The same requests all succeed from a workstation. This is recorded in builders/_fred.py's docstring, and it was found by a probe run on a runner (TEMP: probe FRED endpoints from a GitHub runner (do not merge) #116), because it reproduces nowhere else.
  • workflow_dispatch only runs workflows that exist on the default branch, so a branch-only diagnostic has to ride a pull_request trigger (a draft PR). A workflow that exists on main can be dispatched with --ref <branch> to run that branch's copy (run 35319536981, 2026-09-18).
  • The stamp's read-back guard earns its keep. It refused a date-shaped date_range.end on the first multi-file stamp (YAML reads it back as a date), and it refused a foreign summary on the first pr-body test.
  • Manifest prose must not embed a fact that a refresh can change, such as an end year, an observed range or a row count. The stamp rewrites fields, not sentences, and the first refresh PR shipped a stale column description. The rule is in AGENTS.md and builders/_template.py. Three comments in gdp_growth_annual.csv.yml still break it, and C rewrites them.
  • The dataset dispatch input and the per-builder canary legs were both wrong on their first outing and were set right in FRED from GitHub runners: no custom User-Agent; canary one leg per builder #117. A builder that writes a set of files now runs once.
  • The FRED composite's UNRATE and CPILFESL are empty for 2025-10, the month BLS never published. The 1929–42 series is the column M0892AUSM156SNBR, and the lecture's rename to UNRATE still applies.
  • lecture-wasm's README rule "never edit lectures here; sync from intro's wasm branch" is dead. That branch is 130 commits behind intro main (its last commit was on 2025-04-24), and lecture-wasm PRs edit lectures/ directly.
  • lecture-wasm's lectures/myst.yml excludes seven lectures, not the eight that Include business_cycle: what it reads, what data-lectures now serves, and the sequence lecture-wasm#70 counts: short_path has been enabled since at least 2026-06-11, though the README still lists it as unsupported. Of the lectures that issue names as reading this repo, heavy_tails and inequality are excluded and 404 on the live site, while mle and simple_linear_regression, which it does not name, do read this repo.
  • lecture-wasm's ci.yml builds only on a push to main or on a pull request. A workflow_dispatch of it builds nothing, and it has no repository_dispatch.
  • The canary has fired for real once, on a genuine FRED fetch timeout (refresh-snapshots: a dynamic snapshot's builder is failing #115: exit 1, open for 22 minutes on 2026-09-01). The validation class (exit 2) was shown on 2026-09-30 by an induced failure (Show the snapshot canary catching an induced validation failure (P4) #147).
  • A job-level if: with no status function gets an implicit success(). So a failed canary skips the refresh job through two conditions at once: the explicit needs.canary.result == 'success' and the implicit one. A run cannot show which of them did the work (Show the snapshot canary catching an induced validation failure (P4) #147).
  • The canary's failure artifacts are kept for seven days, so a record of a canary run should quote its key log lines rather than only link to it. notify's issue text begins "The weekly sources-alive canary failed" even when the run was dispatched.
  • Rewrite MLE as an elementary lecture on maximum likelihood lecture-python-intro#849 (merged 2026-09-29) added a yfinance read to intro's mle, and the strict audit fails on it until it is annotated (audit: annotate intro mle's yfinance read #151). A lecture repo's merge can turn this repo's audit red with no change here, so a block's dry-run needs a green main first.
  • Pyodide 0.27.0 ships pandas 2.2.3, whose pct_change pads interior holes forward and warns about it. Intro builds on pandas 3, which does neither, so B passes fill_method=None to keep its figures the same as intro's.
  • FRED labels USREC and M0892AUSM156SNBR "Copyrighted: Citation Required" as well as UMCSENT, and gives M0892AUSM156SNBR as seasonally adjusted. The manifests had both wrong until licence: rest UMCSENT on Michigan's FAQ and record FRED's caching clause #152.
  • api.worldbank.org/v2 sends access-control-allow-origin: *, contrary to what Include business_cycle: what it reads, what data-lectures now serves, and the sequence lecture-wasm#70 assumed; only FRED's fredgraph.csv sends none. Whether wbgapi itself could run under Pyodide is untested.

Activity

  1. mmcky commented on Sep 6, 2026

    @mmcky
    ContributorAuthor

    Revision 2026-09-07: block A is done, and it went first after all. The naming policy settled on #113 and landed with the three schema decisions in #124 (merged as c4a286c): business_cycle_data.csv is now gdp_growth_annual.csv, the other three P4 names are confirmed final, and every manifest, the builder, migration.yml and CATALOG.md follow. #120, #121, #122 and #113 are closed; #119 is the only child of #14 left. The measured table at the top is otherwise unchanged (no refresh was due; the snapshots are the 2026-09-01 vintage).

    Two facts for block B, measured this session rather than assumed: the Netlify deploy-preview check is red on every lecture-wasm PR (QuantEcon/lecture-wasm#62 is still true as of #68 on 2026-09-01) while build-and-deploy passes, so B's gate — the lecture runs end to end in the browser — has to use the workflow's own CLI preview URL, not the Netlify status; and the four URLs the lecture will read are now frozen: raw.githubusercontent.com/QuantEcon/data-lectures/main/lectures/{gdp_growth_annual,unemployment_rate_annual,private_credit_to_gdp,us_business_cycle_monthly}.csv.

    Resume pointer: block B next, as a draft PR in ../lecture-wasm for approval. Block C's manifest flip should also add the consumers entry to all four files in one PR, since the nulls: placement blocks and the YR(\d{4}) patterns now mean a manifest edit touches lines the shared validator will read.

  2. mmcky commented on Sep 7, 2026

    @mmcky
    ContributorAuthor

    Revision 2026-09-07 (later): block E's "#14's remaining half" is done. #119 landed in #126 (merged as 818811b): the shared manifest-driven validate() in builders/_validate.py, both dynamic builders delegating to it, and validate-datasets.yml running conformance for all 44 manifests and byte validation for every CSV on each PR. #14 is closed; nothing from it is left on this plan.

    One consequence for block B and C: the FRED manifest now says recent: 1 and carries no exact null counts, because the validator's first live dry-run showed UMCSENT, CPILFESL and INDPRO unpublished for the newest month. The flip in block C should therefore expect the monthly refresh PRs to add one row with three blanks in it, which is correct, not a defect.

    Resume pointer unchanged: block B next, the lecture-wasm draft PR against the four frozen URLs.

  3. added theissue type on Sep 29, 2026
  4. changed the title [-]Work plan — P4 dynamic snapshots: lecture-wasm adoption of the business_cycle set[/-] [+]lecture-wasm dynamic snapshots: business_cycle reads the four data-lectures snapshots (P4)[/+] on Sep 29, 2026
  5. mmcky commented on Sep 29, 2026

    @mmcky
    ContributorAuthor

    Revision 2026-09-29: this plan is now the tracker for its own project. On 2026-09-29 @mmcky ruled that lecture-wasm's adoption of the business_cycle snapshots, which until then was Track E of the datasets migration, is a project of its own: wasm-dynamic-snapshots in the status-projects registry (programme infrastructure, active, priority next, started 2026-09-01), with this issue as its tracker. The static migration finished on 2026-08-18 and now closes without it. qeld is registered separately, as the proposed qeld-package project.

    Why this issue. It has carried this work's plan since 2026-09-01, so the tracker dates from the day the work began.

    What moved where.

  6. mmcky commented on Sep 30, 2026

    @mmcky
    ContributorAuthor

    Revision 2026-09-30: the canary proof is done, decisions 1 and 2 are taken, and blocks B and C are open as draft PRs.

    The stamp is re-dated to 2026-09-30 after re-checking every row of the table. The body now carries the decisions, the new deadline for #151 and four facts learned today. Still open: decision 3 (on_refresh, set to rebuild in #153) and decision 4 (who merges the monthly refresh PRs).

  7. mmcky commented on Sep 30, 2026

    @mmcky
    ContributorAuthor

    Revision 2026-09-30 (later): #151 and #152 merged. #151 (05:02 UTC) annotated intro's mle yfinance read, so main's strict audit is green again. #152 (05:10 UTC) recorded the UMCSENT and FRED licence decisions. The audit-dashboard runs on main after each merge passed and deployed.

    Block C (#153) rebases cleanly onto the new main. Its dry-run there gives exactly what #146 expects, with no stand-in annotation now that #151 is real: the landed records with B's branch exit 1 with 4 warnings, C with B's branch exits 0, and C with lecture-wasm's main exits 1. The two deadline rows these PRs met are removed from the body.

    Next: the first monthly refresh (expected Monday 2026-10-05), then Run all on QuantEcon/lecture-wasm#85's preview, then B and C on the same day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions