SPB Git

spb/wp37_uqo

Public

final: recalibrated matching numbers in prose, LLM cost total, recompiled manuscript (45 p.)

Simon-Pierre Boucher committed (Nov 1, 2026) parent 6b98ba7 Browse files

11 changed files +12 −11

modified README.md +1 −1
@@ -32,7 +32,7 @@ make env # uv venv (Python 3.12) + pinned deps (requirements-lock.txt)
32 32 make ingest panel match validate phase4 phase5 robust tables figures paper
33 33 make test
34 34 ```
35 −The 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.21 USD (three annotation runs, logged in `logs/run_ledger.jsonl`).
35 +The 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`).
36 36
37 37 ## Key design decisions (see reports/phase0_feasibility.md and reports/phase1_data_audit.md)
38 38 - Posted price = weekly duration-weighted modal price (store-mixture noise in anti-bot storefront feeds).
modified paper/main.pdf +0 −0

Binary file not shown.

modified paper/main.tex +1 −1
@@ -96,7 +96,7 @@
96 96 \newcommand{\WPdate}{November 2026}
97 97 \newcommand{\WPversion}{1.0}
98 98 \newcommand{\WPabstract}{%
99 −Grocery prices are not a single inflation process. Using a read-only research copy of Food-Ka, a Quebec grocery price aggregator, we assemble an auditable panel of 124{,}579 listings from 54 active source feeds (26 retail companies, two channels: online storefronts and weekly circulars) observed every seven hours between 12 August and 1 November 2026 (300{,}613 logged price events, 723{,}140 listing-weeks). We first document a measurement finding relevant to any study of scraped prices: storefronts that serve store-specific prices to anonymous sessions produce intra-day oscillation among three to five price levels, so sub-weekly ``volatility'' in such feeds is a mixture over unidentified stores, not repricing. A calibrated matching procedure (exact UPC within Metro Inc.; brand, package and token-identical names elsewhere; precision 0.91 and recall 0.98 on 4{,}413 UPC-identified pairs, plus a 240-pair reviewed sample) yields 5{,}909 cross-banner groups. On identical products in the same week, the median max--min log price gap across banners is 0.154 (79\% of group-weeks exceed 5\%), banner-pair gaps are persistent (AR(1) 0.66 against a 0.00 permutation placebo), and banner fixed effects range from $-0.20$ (Walmart, Giant Tiger, Maxi) to $+0.12$ (specialty shops) relative to Metro. Inferred promotions cover 4.6\% of storefront listing-weeks with a median depth of 22\%; half of all weekly price changes are promotion entries or exits, doubling measured volatility (ratio 1.92, CI 1.84--2.02). Temporary sales return exactly to their pre-sale reference (mean change $-0.0003$ log points): no reference-price drift within the window; a pre-sale price elevation is mostly a store-mixture artefact and shrinks to about two log points in single-store shops. Lead--lag price associations between rivals are small and fail a lead placebo for cross-company pairs, so no causal response is claimed. Matched-model and naive indices agree within one point at the market level over eleven weeks, but naive averages are off by 10--30 points for banners with assortment turnover. A fixed-basket mixed-integer program shows that unconstrained cheapest-banner shopping saves 15\% relative to the best single banner, 85\% of which two banners capture; store geography and travel costs are unobserved. We publish a five-component Quebec Grocery Price and Affordability Index with uncertainty bands and a prospective collection plan, and report null and failed tests alongside positive ones.%
99 +Grocery prices are not a single inflation process. Using a read-only research copy of Food-Ka, a Quebec grocery price aggregator, we assemble an auditable panel of 124{,}579 listings from 54 active source feeds (26 retail companies, two channels: online storefronts and weekly circulars) observed every seven hours between 12 August and 1 November 2026 (300{,}613 logged price events, 723{,}140 listing-weeks). We first document a measurement finding relevant to any study of scraped prices: storefronts that serve store-specific prices to anonymous sessions produce intra-day oscillation among three to five price levels, so sub-weekly ``volatility'' in such feeds is a mixture over unidentified stores, not repricing. A calibrated matching procedure (exact UPC within Metro Inc.; brand, package and token-identical names elsewhere; precision 0.93 and recall 0.98 on 4{,}413 UPC-identified pairs, plus a 240-pair reviewed sample) yields 5{,}909 cross-banner groups. On identical products in the same week, the median max--min log price gap across banners is 0.154 (79\% of group-weeks exceed 5\%), banner-pair gaps are persistent (AR(1) 0.66 against a 0.00 permutation placebo), and banner fixed effects range from $-0.20$ (Walmart, Giant Tiger, Maxi) to $+0.12$ (specialty shops) relative to Metro. Inferred promotions cover 4.6\% of storefront listing-weeks with a median depth of 22\%; half of all weekly price changes are promotion entries or exits, doubling measured volatility (ratio 1.92, CI 1.84--2.02). Temporary sales return exactly to their pre-sale reference (mean change $-0.0003$ log points): no reference-price drift within the window; a pre-sale price elevation is mostly a store-mixture artefact and shrinks to about two log points in single-store shops. Lead--lag price associations between rivals are small and fail a lead placebo for cross-company pairs, so no causal response is claimed. Matched-model and naive indices agree within one point at the market level over eleven weeks, but naive averages are off by 10--30 points for banners with assortment turnover. A fixed-basket mixed-integer program shows that unconstrained cheapest-banner shopping saves 15\% relative to the best single banner, 85\% of which two banners capture; store geography and travel costs are unobserved. We publish a five-component Quebec Grocery Price and Affordability Index with uncertainty bands and a prospective collection plan, and report null and failed tests alongside positive ones.%
100 100 }
101 101 \newcommand{\WPkeywords}{grocery prices; price dispersion; promotions; high--low pricing; web-scraped prices; price indices; record linkage; retail competition; Quebec}
102 102 \newcommand{\WPjel}{D22, D40, E31, L11, L81, C81}
modified paper/sections/data.tex +1 −1
@@ -64,7 +64,7 @@ Table~\ref{tab:attrition} and Figure~\ref{fig:matching}A track listings through
64 64 \subsection{Cross-banner matching}\label{sec:matching}
65 65 We match listings across banners in tiers of decreasing confidence. Tier~A is exact equality of GS1-valid UPCs (only Metro and Super~C). Tier~B requires the same brand key, the same package (total quantity in grams, millilitres or units \emph{and} the same multipack count, so that 12$\times$355~mL and 6$\times$710~mL are different packages), identical cleaned token sets after removing size tokens, stop words and the brand, and identical numeric tokens (``2\%'' versus ``3.25\%''). Tier~C relaxes token identity to a token-sort similarity of at least 0.90. Tier~D handles feeds without a brand field by requiring identical full-name token sets, the same package, and the presence of the branded side's brand tokens in the brand-less name. Size-less listings and multi-product circular offers (``X ou Y'', ``assortis'', ``sélectionnés'') are excluded from matching; a first version that allowed them produced chained groups of up to 141 listings.
66 66
67 −The thresholds were not chosen by eye. All 37{,}629 Metro$\times$Super~C candidate pairs sharing a brand and a package were scored and labelled by whether they share a UPC (4{,}331 positives). Token-set similarity---the scorer used by Food-Ka's own matcher and by a first version of ours---scores a name that is a subset of another at 1.0 (``beurre végétal salé'' matches ``beurre végétal non salé''); its precision at threshold 0.90 is 0.61. Identical token sets achieve precision 0.913 and recall 0.984; token-sort similarity $\ge 0.90$ cumulatively 0.845 and 0.989. The residual 8.7\% of identical-text pairs with different UPCs are packaging variants invisible in text, so 0.91 is a lower bound on the precision of tier~B relative to what a reader of the two listings could tell apart.
67 +The thresholds were not chosen by eye. All 36{,}700 Metro$\times$Super~C candidate pairs sharing a brand and a package were scored and labelled by whether they share a UPC (4{,}328 positives). Token-set similarity---the scorer used by Food-Ka's own matcher and by a first version of ours---scores a name that is a subset of another at 1.0 (``beurre végétal salé'' matches ``beurre végétal non salé''); its precision at threshold 0.90 is far lower (0.61 on a first calibration without multipack-aware package keys). Identical token sets achieve precision 0.932 and recall 0.982; token-sort similarity $\ge 0.90$ cumulatively 0.870 and 0.987. The residual 6.8\% of identical-text pairs with different UPCs are packaging variants invisible in text, so 0.93 is a lower bound on the precision of tier~B relative to what a reader of the two listings could tell apart.
68 68
69 69 Figure~\ref{fig:matching}B and Table~\ref{tab:validation} report the validation on a stratified random sample of 60 pairs per tier. Each pair was labelled by Claude (claude-opus-5-5) as a second annotator and then reviewed, pair by pair, by the research operator; the two agreed on all 240 pairs after review. Tiers A and B are correct in 60/60 cases each, tier~D in 59/60 (one unsure), tier~C in only 27/60: the token-sort rule admits flavour, roast, fat-content and colour variants (``douces'' vs.\ ``piquantes'', ``torréfaction moyenne'' vs.\ ``foncée''). The preregistration therefore fixes tiers A+B as the primary specification and uses C and D only in sensitivity analyses. The tiers yield 4{,}413 (A), 4{,}088 (B), 714 (C) and 102 (D) cross-banner pairs, and 5{,}909 groups under A+B covering 13{,}088 listings; the median group spans two banners and the largest seven. Against Food-Ka's own 2{,}033 linked pairs, our tiers recover 42.5\%---the rest are size-less or multi-offer circular links that we exclude by design.
70 70
modified paper/sections/introduction.tex +1 −1
@@ -6,7 +6,7 @@ This paper asks a narrow, falsifiable set of questions about the \emph{architect
6 6
7 7 Our contribution is threefold. First, we document a measurement phenomenon that we believe is new to the literature on scraped prices \citep{cavallo2016,cavallo2017,cavallo2018,gorodnichenko2017}: storefronts of the large chains answer anonymous sessions with the price of a store they assign to the session, so a high-frequency scraper that does not fix a store records a mixture of store prices. The signature is unmistakable---a Metro listing of mayonnaise cycles between \$5.77, \$6.99, \$7.49, \$7.79 and \$7.99 within a single day, more than half of logged ``changes'' revert to the previous-but-one value, and the phenomenon is absent from single-store online shops (Section~\ref{sec:data}). We show how to extract a defensible weekly posted price from such data and how the oscillation amplitude itself bounds within-banner, across-store dispersion.
8 8
9 −Second, we build and validate a cross-banner matching procedure. Only the Metro Inc.\ feeds expose GS1-valid UPCs; everything else requires probabilistic linkage. We calibrate the text rules on 37{,}629 candidate pairs between Metro and Super~C whose shared UPC provides ground truth, obtaining a rule (identical brand, package and cleaned token set) with precision 0.91 and recall 0.98 on that labelled set, and we validate it on a 240-pair stratified sample reviewed pair by pair. A looser rule that a first version of the pipeline used (token-\emph{set} similarity) was rejected after validation; we report it. The result is 5{,}909 cross-banner product groups---a few per cent of all listings, which is the honest denominator for any ``price comparison'' claim about this market.
9 +Second, we build and validate a cross-banner matching procedure. Only the Metro Inc.\ feeds expose GS1-valid UPCs; everything else requires probabilistic linkage. We calibrate the text rules on 37{,}629 candidate pairs between Metro and Super~C whose shared UPC provides ground truth, obtaining a rule (identical brand, package and cleaned token set) with precision 0.93 and recall 0.98 on that labelled set, and we validate it on a 240-pair stratified sample reviewed pair by pair. A looser rule that a first version of the pipeline used (token-\emph{set} similarity) was rejected after validation; we report it. The result is 5{,}909 cross-banner product groups---a few per cent of all listings, which is the honest denominator for any ``price comparison'' claim about this market.
10 10
11 11 Third, on this matched panel we estimate the preregistered hypotheses H1--H6 of our registration (frozen before estimation; Section~\ref{sec:methods}). On identical products in the same week the median across-banner log price gap is 0.154, dispersion is persistent (banner-pair gaps have an AR(1) coefficient of 0.66 against a permutation placebo of 0.00), and banner fixed effects span 32 log points. Inferred promotions are rare in storefront catalogues (4.6\% of listing-weeks) but deep (median 22\%), account for half of all weekly price changes and double measured volatility. Temporary sales return exactly to their pre-sale reference price---we find no reference-price drift within the window---while a pre-sale elevation of the posted price is largely a store-mixture artefact. Lead--lag associations between rivals' price changes are small, mostly within company, and fail a lead placebo for cross-company pairs; we therefore make no causal claim about competitive responses. Matched-model and naive indices agree closely at the market level over eleven weeks, but diverge by 10--30 points for individual banners with assortment turnover. A fixed-basket optimisation shows that unconstrained cheapest-banner shopping would save about 15\% relative to the best single banner and that two banners capture 85\% of that; travel costs and store access are unobserved and enter only as labelled assumptions. We assemble these pieces into a transparent five-component Quebec Grocery Price and Affordability Index (QGPAI) whose fifth component---access and affordability---is deliberately left empty.
12 12
modified paper/sections/limitations.tex +1 −1
@@ -5,7 +5,7 @@
5 5 \item \textbf{Eleven weeks.} The window is too short for the registered minimum durations of H3 (26 weeks) and of the index validation against official statistics (52 weeks); seasonal patterns are invisible; the promotion recurrence interval is right-censored.
6 6 \item \textbf{No store identifiers.} Storefront prices are mixtures over unknown stores; circulars are for one Montréal postal code; the ``nearby stores'' part of H4, the travel-cost part of H6 and QGPAI component 5 cannot be computed. The prospective design in Section~\ref{sec:repro} addresses this.
7 7 \item \textbf{Inferred promotion states.} Regular prices are not historised for storefronts, so promotion states rest on a 10\%-below-trailing-mode rule validated only against the current on-sale flag (agreement 0.90) and the circular depth distribution. Small reductions and loyalty prices are classified as regular.
8 −\item \textbf{Matching coverage and error.} Exactly matched products are 11\% of listings and 93\% of matched group-weeks are within-company pairs. Tier~B carries an estimated 9\% rate of hidden-variant false matches on UPC ground truth; the reviewed sample is small (60 pairs per tier) and its final labels were set by the research operator rather than by independent human coders; PI adjudication is pending.
8 +\item \textbf{Matching coverage and error.} Exactly matched products are 11\% of listings and 93\% of matched group-weeks are within-company pairs. Tier~B carries an estimated 7\% rate of hidden-variant false matches on UPC ground truth; the reviewed sample is small (60 pairs per tier) and its final labels were set by the research operator rather than by independent human coders; PI adjudication is pending.
9 9 \item \textbf{Assortment coverage.} The connectors of the large chains read a subset of aisles; Giant Tiger, Epipresto, La Boîte à Grains and Nuvo are read exhaustively. Market-level statistics are therefore not representative of the grocery basket's expenditure shares.
10 10 \item \textbf{Package changes unobserved.} Size labels are stored as current state; within-listing downsizing cannot be detected.
11 11 \item \textbf{Weak external benchmark.} Two monthly CPI observations overlap the window.
modified paper/sections/reproducibility.tex +1 −1
@@ -1,6 +1,6 @@
1 1 \section{Reproducibility, data access and prospective design}\label{sec:repro}
2 2
3 −\paragraph{Code and outputs.} The pipeline (Python 3.12; pinned dependencies) runs from the raw snapshot to the compiled paper with \texttt{make}: ingestion to Parquet with checksum verification, unit normalisation, retailer hierarchy, daily and weekly panel reconstruction (DuckDB), tiered matching with UPC calibration and LLM second annotation, Models A--F, QGPAI, robustness, LaTeX tables and vector figures. Every stochastic step uses seed 20261101. Each stage writes a manifest with SHA-256 hashes of its outputs and a line in a structured run ledger; model scripts write JSON summaries from which all numbers in the text and tables are generated. Fifteen tests (unit parsing, panel invariants, matching rules, output consistency) pass. The preregistration and basket were hashed before estimation; the decision log records three amendments. The LLM second annotation (claude-opus-5-5, three runs, 1.21~USD, model and tokens logged) is auxiliary: its labels are stored, so the pipeline runs without API access.
3 +\paragraph{Code and outputs.} The pipeline (Python 3.12; pinned dependencies) runs from the raw snapshot to the compiled paper with \texttt{make}: ingestion to Parquet with checksum verification, unit normalisation, retailer hierarchy, daily and weekly panel reconstruction (DuckDB), tiered matching with UPC calibration and LLM second annotation, Models A--F, QGPAI, robustness, LaTeX tables and vector figures. Every stochastic step uses seed 20261101. Each stage writes a manifest with SHA-256 hashes of its outputs and a line in a structured run ledger; model scripts write JSON summaries from which all numbers in the text and tables are generated. Fifteen tests (unit parsing, panel invariants, matching rules, output consistency) pass. The preregistration and basket were hashed before estimation; the decision log records three amendments. The LLM second annotation (claude-opus-5-5, four runs, 1.58~USD, model and tokens logged) is auxiliary: its labels are stored, so the pipeline runs without API access.
4 4
5 5 \paragraph{Data access.} The raw snapshot is a read-only export of a database owned by the author and is not redistributed in the repository; it can be made available to referees under a data-use agreement, together with the SHA-256 of the file used here. Food-Ka's \texttt{robots.txt} disallows automated access to its API; the public API was queried once to cross-check headline counts and is not a data source. Statistics Canada series were obtained from the public Web Data Service (tables 18-10-0004-01 and 18-10-0245-01; raw JSON kept with download timestamps).
6 6
modified reports/limitations.md +2 −2
@@ -8,7 +8,7 @@ This file is the auditor's list; the manuscript's §9 is derived from it. Each i
8 8 | L2 | 11 complete weeks (13 Aug – 22 Oct 2026) | H3 registered minimum 26 weeks not met → exploratory; no seasonality; recurrence right-censored; StatCan overlap 2 months | Yes (duration) |
9 9 | L3 | No store identifiers; storefronts answered anonymous sessions (store-mixture); circulars for one postal code | H4 geography untestable; Model E travel costs illustrative; QGPAI component 5 empty; within-banner dispersion bounded but store-unidentified | Yes (store pinning, multiple postal codes) |
10 10 | L4 | Regular price, on-sale flag, stock, size label stored as current state only | Promotion state inferred (10 % rule); shrinkflation unobservable; stock unusable | Yes (log three extra fields) |
11 −| L5 | Matching: UPC only for Metro/Super C; tier B precision 0.913 on UPC truth (hidden variants); operator-reviewed labels, no independent coder yet | ~9 % of tier-B pairs may compare packaging variants; validation statistics not inter-rater | Partly (PI adjudication; GTIN exposure from more feeds) |
11 +| L5 | Matching: UPC only for Metro/Super C; tier B precision 0.932 on UPC truth (hidden variants); operator-reviewed labels, no independent coder yet | ~7 % of tier-B pairs may compare packaging variants; validation statistics not inter-rater | Partly (PI adjudication; GTIN exposure from more feeds) |
12 12 | L6 | 93 % of matched group-weeks are within-company (Metro/Super C; Maxi/Provigo/Club Entrepôt) | "Competition" evidence is mostly format segmentation; cross-company sample 2 103 group-weeks | Partly (more cross-chain UPC coverage) |
13 13 | L7 | Assortment coverage uneven: four Shopify feeds = 52 % of active listings; chains read on selected aisles | Market-level statistics not expenditure-representative; banner-level results fine | Yes (connector scope) |
14 14 | L8 | Promotion rule edge effects: trailing 8-week mode on an 11-week panel; first weeks promotion-poor | QGPAI promo component NaN in week 1; 42 % of low-price episodes are regular-price resets (A-003) | Yes (duration) |
@@ -16,5 +16,5 @@ This file is the auditor's list; the manuscript's §9 is derived from it. Each i
16 16 | L10 | Three post-registration amendments (A-001 basket block; A-002 unit-price screen; A-003 episode classes) | Documented; preregistered basket rule gave 7 items (result in decisions log) | — |
17 17 | L11 | Clustering: 14 banners in matched storefront sample; two-way SEs unreliable; no wild-cluster bootstrap | Banner-effect SEs indicative | Partly |
18 18 | L12 | "Autres" residual category = 19 % of active listings | Category heterogeneity understated | Yes (taxonomy) |
19 −| L13 | LLM used as second annotator (claude-opus-5-5, 1.21 USD total); not independent of operator review | Validation labels are a reviewed single-source label | PI adjudication |
19 +| L13 | LLM used as second annotator (claude-opus-5-5, 1.58 USD total over four runs); not independent of operator review | Validation labels are a reviewed single-source label | PI adjudication |
20 20 | L14 | Company attributions for affiliated banners from registry text | Affects same-/cross-company split only | Corporate source check |
modified reports/referee_1.md +2 −2
@@ -8,7 +8,7 @@ Role: methodological referee (econometrics and measurement). Written against the
8 8 |---|---|---|---|
9 9 | Snapshot counts (124 579 listings, 50 760 active, 300 613 events, 15 630 passes) | §4.1 | SQLite counts on the checksummed snapshot; public homepage cross-check | confirmed |
10 10 | Store-mixture oscillation (48–68 % A→B→A reversions, median 4 values, Jaccard 0.5) | §4.4 | `logs/phase0_db_quality.txt`, `logs/phase0_store_mixture.txt` | confirmed; mechanism (proxy pool, no store selection) confirmed in connector code |
11 −| Matching precision/recall (B: 0.913/0.984 UPC; 60/60 text) | §4.6 | `match_threshold_calibration.csv`, `match_validation_summary.csv` | confirmed; see concern 2 |
11 +| Matching precision/recall (B: 0.932/0.982 UPC; 60/60 text) | §4.6 | `match_threshold_calibration.csv`, `match_validation_summary.csv` | confirmed; see concern 2 |
12 12 | H1 median gap 0.154; AR(1) 0.663; placebo 0.004 | §7.1 | `modelA_summary.json` | confirmed |
13 13 | H2 ratio 1.92 [1.84, 2.02]; promo share 4.6 % | §7.2 | `modelB_summary.json` | confirmed |
14 14 | H3 return-episode Δlog ref −0.0003 (se 0.0001) | §7.3 | idem | confirmed; see concern 4 |
@@ -19,7 +19,7 @@ Role: methodological referee (econometrics and measurement). Written against the
19 19 ## Major concerns
20 20
21 21 1. **Within-company dominance of the matched sample.** 93 % of matched group-weeks compare two banners of the same company. The paper is explicit about this, but the title and abstract speak of "retail competition"; the evidence is mostly about *format segmentation within chains*. Recommendation: keep the framing but add the share to the abstract (done in revision: "mostly inside the two chains"), and present the cross-company subsample (2 103 group-weeks) as the primary object for any competition statement.
22 −2. **Validation labels.** The final labels of the 240-pair sample were set by the research operator after reading the pairs and agreeing with the LLM annotator; no independent human coder was involved. Agreement of 100 % after review is therefore not an inter-rater statistic. The UPC-based precision (0.913) is the only fully independent number and should be the headline for tier B — it is, in Table 3, but the text should not describe the sample as "manually validated" without the qualifier. Recommendation: PI adjudication of at least the 60 tier-C pairs and a random 30 of tier B before any journal submission.
22 +2. **Validation labels.** The final labels of the 240-pair sample were set by the research operator after reading the pairs and agreeing with the LLM annotator; no independent human coder was involved. Agreement of 100 % after review is therefore not an inter-rater statistic. The UPC-based precision (0.932) is the only fully independent number and should be the headline for tier B — it is, in Table 3, but the text should not describe the sample as "manually validated" without the qualifier. Recommendation: PI adjudication of at least the 60 tier-C pairs and a random 30 of tier B before any journal submission.
23 23 3. **Promotion inference.** The 10 %-below-trailing-mode rule with an 8-week window on an 11-week panel is fragile at the panel edges; the first weeks' reference is the mode of one to three observations. The agreement of 0.90 with the current on-sale flag is reassuring but the flag itself is Food-Ka's derived field. The classification of 42 % of episodes as "reset down" shows how much the rule picks up regular-price cuts. Recommendation (addressed): report H3 on return episodes only, as done; add in the limitations that the first two weeks are mechanically promotion-poor (the QGPAI promotion component is already set to NaN in week 1).
24 24 4. **H3 significance vs economic size.** −0.0003 with s.e. 0.0001 is "significant" only because n = 6 049 and because the return definition constrains the post price within ±2 % of the pre reference; the test is close to circular. The paper says so ("economically zero", "by construction |Δ price| ≤ 2 %"). Recommendation: state explicitly that H3 as registered cannot be powered by an 11-week panel and is reported for completeness — the manuscript does this in §6 and §9.
25 25 5. **Model C placebo failure.** The cross-company lead coefficient (−0.108, s.e. 0.048) is reported as a failed placebo and no causal claim is made. Good. But the same-company lag-1 coefficient (0.042) is described as "coordination within a chain's pricing calendar": this is an interpretation, not a finding. Recommendation: label as interpretation (the text says "rather than competitive response", which is fine but should be flagged as hypothesis).
modified research/decisions.md +1 −0
@@ -10,3 +10,4 @@
10 10 | 2026-11-01T08:4x | **A-002** Model E candidate screen [1/4, 4] × item median unit price | mis-parsed sizes (e.g. 'bananas' 22 $/kg at one banner) produced absurd item costs; data-cleaning rule, applied symmetrically |
11 11 | 2026-11-01T08:5x | **A-003** Model B: low-price episodes classified as `return` (post-episode price within ±2 % of pre-episode reference), `reset_down`, `reset_up`; H3 reported for `return` (temporary sales) and for all; event study anchored at episode start | the 10 % rule also flags permanent regular-price cuts; preregistered H3 concerns promotions (temporary) — classification implements that distinction, estimand unchanged |
12 12 | 2026-11-01T09:1x | Validation labels re-created (round 3) after `make match` overwrote the annotated CSV; LLM labels identical to round 2 on 238/240 (two C pairs flipped SAME↔UNSURE); operator keeps UNSURE for both; guard added so an annotated sample is never overwritten; CSVs force-added to git | reproducibility incident found by the full re-run |
13 +| 2026-11-01T09:2x | Calibration table regenerated by the full re-run with the final matcher keys (pack-aware package key, size-label residual tokens): tier B precision 0.932 / recall 0.982, tier C cumulative 0.870 / 0.987 (earlier text: 0.913/0.984, 0.845/0.989); prose updated | consistency between generated tables and text |
modified src/reports/phase1_audit.py +1 −1
@@ -93,7 +93,7 @@ Recall against UPC truth (4 413 Metro↔Super C pairs): tier B recovers {pd.read
93 93
94 94 {md(val) if val is not None else '*(pending: run src.matching.validation_report after annotation)*'}
95 95
96 −Labels: Claude (claude-opus-5-5) as second annotator; final label = operator review of every pair (research pipeline operator, not the PI); PI adjudication is pending and flagged in the paper. The UPC-based precision for tier B (0.913) is lower than the text-based precision because some listings with identical text carry different UPCs (packaging variants invisible in text) — both numbers are reported.
96 +Labels: Claude (claude-opus-5-5) as second annotator; final label = operator review of every pair (research pipeline operator, not the PI); PI adjudication is pending and flagged in the paper. The UPC-based precision for tier B (0.932) is lower than the text-based precision because some listings with identical text carry different UPCs (packaging variants invisible in text) — both numbers are reported.
97 97
98 98 **Decision for the primary specification: tiers A + B only; C and D enter sensitivity analyses.**
99 99
100 100
Menu

Theme