WP37 — The Hidden Architecture of Grocery Prices: Promotions, Retail Competition, and the Cost of Living in Quebec
UQO Working Paper No. 37 — Simon-Pierre Boucher, Département des sciences administratives, Université du Québec en Outaouais. Version 1.0, November 2026.
Reproducible research pipeline built on a read-only snapshot of the Food-Ka database (owner export, 2026-11-01). Nothing in production was modified; the raw snapshot is not committed (data/raw/README.md documents provenance and checksum).
Layout
CLAUDE.md mandate (verbatim)
config/settings.yaml paths, seed (20261101), snapshot identity, scope
config/basket.yaml preregistered 30-item basket (frozen)
research/preregistration.md frozen hypotheses H1–H6, estimands, analysis plan (sha256 in research/decisions.md)
research/decisions.md decision log and amendments A-001 … A-003
src/ingestion snapshot → parquet; Statistics Canada WDS benchmarks
src/cleaning unit normalisation, retailer hierarchy, daily/weekly panel reconstruction, coverage
src/matching tiered cross-banner matching, UPC calibration, LLM second annotation, validation
src/econometrics matched panels, Model A (dispersion), B (promotions), C (spillovers), robustness
src/indices Model D (indices), Model E (basket MIP), QGPAI
src/forecasting Model F (rolling-origin forecasts)
src/reports Phase 1 audit, LaTeX tables, figures
literature/ seed references, Crossref-verified metadata, evidence matrix
experiments/ JSON summaries of every model
paper/ main.tex, sections/, tables/, figures/, references.bib, main.pdf
reports/ phase0_feasibility, phase1_data_audit, referee_1, referee_2, limitations, reproducibility
logs/ run ledger (md + jsonl), manifests with SHA-256 of outputs, pipeline log
tests/ pytest (units, panel invariants, matching rules, output consistency)Reproduce
make env # uv venv (Python 3.12) + pinned deps (requirements-lock.txt)
make ingest panel match validate phase4 phase5 robust tables figures paper
make testThe LLM second annotation (src/matching/llm_annotate.py) needs ANTHROPIC_API_KEY in .env; its labels are stored in data/processed/match_validation_sample.csv so the rest of the pipeline runs without API access. Total LLM cost of the project: 1.58 USD (four annotation runs, logged in logs/run_ledger.jsonl).
Key design decisions (see reports/phase0_feasibility.md and reports/phase1_data_audit.md)
- Posted price = weekly duration-weighted modal price (store-mixture noise in anti-bot storefront feeds).
- Primary matching tiers A (UPC) + B (brand + package + identical token set); C and D in sensitivity only.
- No store geography, no regular-price history, no quantities: H4 geography and QGPAI component 5 are explicitly not computed.