You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Schema decision: semantics of the column pattern entry for wide files #120
A schema.columns entry carries either name (one exact column) or pattern (a regex matching a run of columns). pattern was proposed in #14 and first used on 2026-09-01; four manifests use it today (business_cycle_data.csv.yml, unemployment_rate_annual.csv.yml, private_credit_to_gdp.csv.yml, chapter_3.xlsx.yml), all for wide files whose column set grows. manifest-schema.yml documents the field but not its semantics, and no validator reads it yet.
To decide before the manifest-driven validate() enforces it:
Regex dialect and anchoring: full-match or search; Python re as the reference.
Ordering and contiguity: must the matched run be contiguous, and in the position it appears in the columns list, or is it a set membership test? business_cycle additionally asserts an unbroken year grid, which is stronger than any regex says.
Minimum run length: does a pattern that matches zero columns pass (schema silent) or fail (file lost its wide part)?
Exhaustiveness: must every column in the file be claimed by exactly one name or pattern entry, so an unexpected column fails validation? (business_cycle's own check says yes.)
Whether date_range for a wide file is derived from the pattern's matched columns, as scripts/snapshots.py already does when stamping date_range.end.
Record the outcome in manifest-schema.yml's comment on pattern, and touch the four manifests only if the decision changes what they mean.
Decision, 2026-09-07: ordered, contiguous, exhaustive, at least one match, and a capture group carries the date
Settled the five questions against what the repo does today rather than in the abstract. Three CSV manifests carry the same entry (YR\d{4}, float64) for the three World Bank tables, each with 68 header columns on an unbroken grid from YR1960 to YR2025; chapter_3.xlsx.yml's sheets_pattern is a sibling key for sheet names and is not covered here. builders/business_cycle.py's hand-written validate() is already stricter than any regex: it requires the year columns to be every column after Country, to start at 1960, to have no gap, and to be float, and it derives date_range.end from the last year column, which scripts/snapshots.py stamp then writes into the manifest. So the de facto semantics were already ordered, contiguous, exhaustive and date-bearing; this records them so the shared validate() (#119) can enforce them.
question
decision
1. dialect and anchoring
Python re, fullmatch — YR\d{4} cannot match YR19601
2. ordering and contiguity
the validator walks columns in order; a pattern entry consumes the maximal run of consecutive matching columns, in the position it appears. Column order is part of the contract because positional reads exist in the lectures
3. minimum run
one. Zero matches fails with "wide part missing". No min_count field until a file needs a floor above one
4. exhaustiveness
every file column must be claimed by exactly one name or pattern entry; an unclaimed column fails
5. date_range for wide files
derived from the matched columns when the pattern has exactly one capture group: YR(\d{4}). The grid check (no gaps) stays builder-specific, layered on top
What the validator reads. The manifest describes the CSV header as written, so the validator reads the raw file with pandas defaults, honouring the manifest's existing delimiter and read_as keys, and no index_col — even though business_cycle.py reads with index_col=0 and sees Country first. The manifest stays a description of the bytes on disk; the read-options half of this is recorded on #122.
Edits this implies.YR\d{4} → YR(\d{4}) in business_cycle_data.csv.yml, unemployment_rate_annual.csv.yml and private_credit_to_gdp.csv.yml (a two-character change that alters nothing about what they mean), and the pattern comment in manifest-schema.yml rewritten to say the above. Both ride with #119 or a small precursor PR; this issue closes when manifest-schema.yml records it.
Activity
mmcky commentedon Sep 6, 2026
Decision, 2026-09-07: ordered, contiguous, exhaustive, at least one match, and a capture group carries the date
Settled the five questions against what the repo does today rather than in the abstract. Three CSV manifests carry the same entry (
YR\d{4}, float64) for the three World Bank tables, each with 68 header columns on an unbroken grid from YR1960 to YR2025;chapter_3.xlsx.yml'ssheets_patternis a sibling key for sheet names and is not covered here.builders/business_cycle.py's hand-writtenvalidate()is already stricter than any regex: it requires the year columns to be every column afterCountry, to start at 1960, to have no gap, and to be float, and it derivesdate_range.endfrom the last year column, whichscripts/snapshots.py stampthen writes into the manifest. So the de facto semantics were already ordered, contiguous, exhaustive and date-bearing; this records them so the sharedvalidate()(#119) can enforce them.re,fullmatch—YR\d{4}cannot matchYR19601columnsin order; apatternentry consumes the maximal run of consecutive matching columns, in the position it appears. Column order is part of the contract because positional reads exist in the lecturesmin_countfield until a file needs a floor above onenameorpatternentry; an unclaimed column failsdate_rangefor wide filesYR(\d{4}). The grid check (no gaps) stays builder-specific, layered on topWhat the validator reads. The manifest describes the CSV header as written, so the validator reads the raw file with pandas defaults, honouring the manifest's existing
delimiterandread_askeys, and noindex_col— even thoughbusiness_cycle.pyreads withindex_col=0and seesCountryfirst. The manifest stays a description of the bytes on disk; the read-options half of this is recorded on #122.Edits this implies.
YR\d{4}→YR(\d{4})inbusiness_cycle_data.csv.yml,unemployment_rate_annual.csv.ymlandprivate_credit_to_gdp.csv.yml(a two-character change that alters nothing about what they mean), and thepatterncomment inmanifest-schema.ymlrewritten to say the above. Both ride with #119 or a small precursor PR; this issue closes whenmanifest-schema.ymlrecords it.Record the four schema and naming decisions: rename, pattern capture …
Manifest-driven validate(): the schema block is the spec, shared by t…