Cross-sectional: 23 US chains (MULTI)
GRADED: VOIDWhat our data showed (facts, frozen at publication)
- Method, frozen here: for each location we take the mean sentiment of the trailing 28 days minus that same location's own baseline (days 29-118). A location qualifies with >=3 recent and >=5 baseline reviews. The chain value is the min(n_recent,30)-weighted mean across its qualifying locations, and a chain qualifies with >=15 of them. 23 of our 79 chains qualified.
- Six most improving: Taco Bell +0.0300 (57 locations), Verizon +0.0140 (27), Subway +0.0072 (75), LA Fitness +0.0052 (16), Wendy's +0.0047 (30), Trader Joe's +0.0023 (16).
- Six most declining: Chipotle Mexican Grill -0.0751 (31 locations), AT&T -0.0472 (17), Shake Shack -0.0428 (41), Domino's -0.0291 (73), Dunkin' -0.0268 (27), In-N-Out Burger -0.0256 (29).
- Magnitudes are asymmetric and we say so before the outcome: only Taco Bell (+0.0300) is clearly rising, while the other five chains in the improving group sit between +0.0140 and +0.0023, which is close to noise. The declining group moves three to thirty times harder (-0.0751 to -0.0256). In practice this entry therefore asks whether the decliners keep declining rather more than it asks whether the improvers keep improving.
- Dispersion across the qualifying universe runs from +0.0300 to -0.0751. The eleven chains between these groups are named in neither and are not part of the test.
- Engine: RSAS v2.1, the production engine. Our own conformal validation shows that a 90% interval for a single chain over a 14-day horizon contains zero for 178 of 178 chains. Single-chain direction is therefore not resolvable from our data, which is precisely why this entry is stated cross-sectionally rather than as a call on any one brand.
- Pre-registered against our own most recent validation window. In the shadow evaluation we ran on 2026-08-27, both our production engine (RSAS v2.1) and its challenger showed a negative mean information coefficient on the clean same-store outcome - -0.070 and -0.034 respectively on weekly folds. The July-August window was anti-persistent. This entry bets on persistence in a regime our own measurement calls anti-persistent. One negative window is not proof of a durable reversal, and flipping the sign to fit it would be overfitting, so we state the tension here rather than after the result is known.
Pre-registered expectation
Over the next 14 days the six chains listed as improving will, as a group, show a higher mean same-store sentiment change than the six listed as declining. This is the 14-day sentiment-persistence relationship (walk-forward IC +0.30) applied across a cross-section. We are not predicting the direction of any individual chain, and we are not predicting any share price.
How this will be graded
- On 2026-09-10 we recompute, for each of the twelve named chains, the forward change: mean same-store sentiment over the window (2026-08-27, 2026-09-10] minus that location's baseline of the 90 days ending 2026-08-27, using the same location filters stated above.
- Sample freshness, fixed here so the decision cannot be made after seeing the result: the grading sample must be no older than 2 days on the grading date. If, on 2026-09-10, the most recent captured review for any of the twelve named chains is staler than that, we re-scrape that chain before grading and record the re-scrape in the grade note.
- HIT if the unweighted mean forward change of the six improving chains exceeds that of the six declining chains. MISS in every other case, including a tie.
- VOID only if fewer than four chains in either group still meet the >=15 matched-location requirement on the grading date. A VOID is published exactly like a HIT or a MISS.
- The grade is computed with RSAS v2.1 - the same engine that produced this entry. Should the engine change before the grading date, this entry is still graded with v2.1.
Sample integrity note (appended 2026-08-29, before grading)
Two things went wrong with this entry after we published it. We are recording both before we know the result, because a disclosure made after the outcome is worth nothing.
1. We contaminated our own sample. On 28 August we ran a burst that deepened our review collection. It worked — one day brought 56,402 reviews against a normal ~4,000 — and it landed very unevenly across the twelve chains named above. Locations passing this entry's filters, recomputed for the pre-registration date of 27 August, using only the data we held that day versus all the data we hold now: Domino's 71 → 177, Dunkin' 27 → 96, Chipotle 31 → 70, AT&T 16 → 28, Verizon 27 → 31, Shake Shack 41 → 44, Subway 75 → 78, In-N-Out 29 → 31, Wendy's 30 → 32, LA Fitness 16 → 17, Taco Bell 58 → 58, Trader Joe's 16 → 16.
The four chains that gained most are all in the declining group. The improving group gained ten locations in total. This entry compares those two groups against each other, so grading on the fuller data would weigh one side of the bet on a substantially rebuilt sample against the other on its original one.
2. We can reproduce the method, but not every number. Reconstructing the sample, we found that the code which produced this entry was never saved — the query was run ad hoc.
Working from the method as written above, the reconstruction matches the entry where it decides the shape of the test: 23 of our 79 chains qualify, exactly as pre-registered. That is not a weak check — a plausible wrong reading of the method, counting by the date we collected a review rather than the date it was written, yields 17.
At chain level it reproduces nine of the twelve location counts exactly. Three differ by one or two locations, in both directions: Domino's −2, AT&T −1, Taco Bell +1. A missing filter produces error in one direction; differences this small running both ways are what window edges produce — timestamps sitting on a boundary, and ties at the ≥3 and ≥5 thresholds.
The failure here is not in the numbers, it is that nobody stored the query. That is now closed: no entry is pre-registered without the code that produced it saved alongside it. Reproducibility is the entire product here, and “almost” does not qualify.
What we are doing, decided before grading. (a) Collection on all twelve chains is frozen until this entry is graded on 10 September; deepening continues on our other 67 chains. (b) The binding grade is the one computed on the frozen sample — the locations as they stood on 27 August, which our point-in-time capture makes recoverable: 437 locations across 12 chains. That is the sample this entry was pre-registered against. (An earlier reconstruction of ours counted 449; 437 is the figure produced by the single definition published here, and it is the one that governs.) (c) We will also publish the grade on the full data, as context and as proof that we are not hiding it — it is not the grade of record, and if the two disagree, the disagreement is published too. (d) The exact definition used for both is published with the grade, so the frozen sample can be rebuilt and checked by anyone.
This note was written and published before either grade was computed. We do not know which way the result goes.
Threshold note: this entry can VOID, and we are saying so now (appended 2026-08-31, before grading)
A third thing about this entry is worth recording before it is graded, because after the result it would only read as an excuse.
The grading rule can end this entry in a VOID, and the reason is arithmetic, not bad luck. The entry qualifies a location with at least 3 reviews in the recent window and at least 5 in the baseline, and qualifies a chain with at least 15 such locations. That filter was set on a 28-day window. Grading applies it to a 14-day one, so the same threshold is roughly twice as hard to clear. Rule 4 then voids the entry if fewer than four chains in either group still hold 15 locations.
We measured how close that is, on a window that cannot tell us anything about the outcome: 13 to 27 August, which closes on the day this entry opens. On that window the binding reading keeps only three of the six improving chains at 15 or more locations - LA Fitness 11, Trader Joe's 13, Wendy's 13 - and would have voided. The declining group keeps five, losing AT&T at 12. The four fragile chains are exactly the four that qualified with 16 or 17 locations at pre-registration: they have no margin, so a thin fortnight drops them out.
We are not changing the rule. We now know that the strict reading points toward VOID on a comparable window while two looser readings of the same sentence would have graded, and that is precisely why the rule stays as written. A threshold moved while holding that knowledge is a moved goalpost, whatever the reasoning attached to it. The ledger exists to make that impossible.
Two things pull the other way, and we state them so this note is not read as a prediction. The grading re-scrape covers all 437 pre-registered locations at once, while the rehearsal window was covered only by our normal collection rotation, which reaches a fraction of them on any given day. Better coverage means more locations clearing the threshold. So VOID is a live possibility, not a forecast.
Finally, the failure recorded in the note above - that the code producing this entry was never saved - is closed for the grade as well. The grading code was written, reviewed and committed on 31 August, before any of the data it will read existed, and it records its own SHA-256 (d53f5ff6e0e9...) in the result, so the published grade names the exact code that produced it. It refuses to grade a sample staler than the two days this entry allows, and it computes the binding reading on the frozen 437 locations, never on a chain re-qualified with today's data.
Grader amendment: the baseline is frozen with the sample, and the freshness gate reads the graded rows (appended 2026-09-01, before grading)
The grading code committed on 31 August (sha256 d53f5ff6e0e9...) was reviewed independently on 1 September - before the grading re-scrape, and before any of the data it will read exists. The review found two defects, both of the kind this ledger exists to catch. We fixed them the same day. The previous hash stays in the note above; the fixed code records a new one, d7643a13507e73eed8621fae722ba578ebd734277364a26d982f545653ee5e25 (commit f6d4597).
First, the baseline was not frozen. The code froze the 437 locations but applied a single capture cutoff - the moment of grading - to both windows. The grading re-scrape reaches every frozen location at once, so it would have pulled in older reviews our rotation had never captured, and those would have landed in the baseline and moved it after pre-registration. The baseline now counts only reviews captured by 27 August, the same cut the frozen sample was made with; the forward window counts reviews captured by the grade. Both cutoffs are written into the result.
Second, the freshness rule was checked against each chain's most recent capture anywhere, while the grade runs on the frozen locations only. A chain could have passed the gate on a location outside the sample. The gate now reads the same rows the grade reads.
What the fix changed, measured on the rehearsal window (13 to 27 August, the only window the code is allowed to read before 10 September): the verdicts did not move - strict VOID, matched HIT, frozen_all HIT, as reported on 31 August - but the per-chain numbers moved for all twelve chains, and Verizon's qualifying locations fell from 15 to 5 once its baseline stopped absorbing later captures. That is the defect made visible: same rule, same locations, different baseline. No rule, threshold or reading has changed.
Sample composition note: 30 of the 437 frozen locations are not the chain they were filed under (appended 2026-09-10, before grading)
Recorded today before the grader runs, so it cannot be read as a reaction to the result. Chronology for the record: the Rule 2 re-scrape of the 437 frozen locations ran at 18:26–18:45 UTC (374 locations returned new reviews, 2,279 reviews saved, all twelve chains now within the two-day freshness rule); this note is written after that re-scrape and before any grade is computed.
30 of the 437 frozen locations (6.9%) are venues that are not the chain they were filed under. All 30 are in Germany. By chain and side of the bet: In-N-Out Burger 25 of 29 (declining group) — Berlin burger restaurants that our location discovery of 12 February filed under a chain that has no restaurants outside the United States; Wendy's 3 of 30 (improving group); Shake Shack 2 of 41 (declining group). The other nine chains: 0. The full list with venue names is published at data/proof_xsec01_foreign_locations.json in our repository (available on request until the repository is public) (sha256 761707b0b7dd09aadd38e865e48e0406aaf252303fa3aeb4e7253dfffe856cc4). It was built from the frozen ids and the venue names only; no review data was used.
How it got in. The sample freeze filtered on operational status, chain visibility, manipulation flags and review counts. It had no country filter and no check that the venue name matches the chain; the chain assignment came straight from location discovery. The heading of this entry, "23 US chains", describes the listed companies, not where the locations are: the frozen sample spans 13 countries (Domino's has 16 of its 71 frozen locations in the United States, Subway 14 of 75). We should have said that on 27 August.
The binding grade is unchanged: the strict reading on all 437 frozen locations, exactly as fixed on 31 August, computed by the unmodified grader (sha256 d7643a13507e73eed8621fae722ba578ebd734277364a26d982f545653ee5e25). Removing locations after seeing the problem but before seeing the result is still a change to the sample, and this ledger does not make those.
What we add instead is a third reading, non-binding: strict, on the 407 frozen locations that remain when the 30 are removed. It is computed by a separate script (scripts/proof_xsec01_context_exclusion.py, sha256 bddb51fe9cd7232d…, commit 8b84288, committed before the grader ran) that imports the grader's own filters and verdict logic and modifies none of them. It will be published next to the binding grade and the full-data context, whatever it shows. If the 30 venues change the verdict, we will say so in plain words.
Rule for the next entry, fixed now: a sample freeze must apply a country filter and the location-quality flag before the ids are frozen. This is mandatory before xsec-02.
Grade (2026-09-10)
BINDING GRADE: VOID — graded 2026-09-10 at 18:57 UTC, on the resolution date, by the grading code committed on 1 September and unchanged since (sha256 d7643a13507e73eed8621fae722ba578ebd734277364a26d982f545653ee5e25, commit f6d4597); the result file records that hash. Rule 2 first: the frozen sample had last been captured on 28 August, so we re-scraped the 437 pre-registered location ids — and only those ids — between 18:26 and 18:45 UTC today (scripts/proof_xsec01_rescrape.py, commit 0443b7a): 374 of the 437 locations returned new reviews, 2,279 reviews were saved, 1,996 duplicates were skipped, and all twelve chains passed the two-day freshness gate before the grade ran. Windows exactly as pre-registered: forward (2026-08-27, 2026-09-10], baseline the 90 days ending 2026-08-27, with the baseline counted only from reviews captured by 27 August (annex #3). THE BINDING READING (strict, frozen sample of 437, min(n,30)-weighted): Rule 4 voids the entry, because fewer than four chains in the improving group still meet the 15-location requirement. Improving group: Taco Bell 37, Subway 23 and Verizon 15 qualify; Wendy's 14, Trader Joe's 11 and LA Fitness 10 fall out — 3 of 6. Declining group: Shake Shack 28, Domino's 28, In-N-Out Burger 26 and Chipotle 20 qualify; Dunkin' 13 and AT&T 8 fall out — 4 of 6. Three plus four is not four plus four, so the entry is VOID, and the unweighted sensitivity check says the same. This is the arithmetic we described on 31 August (annex #2): a filter of at least 3 reviews per location, set on a 28-day window, applied to a 14-day one, and four chains that qualified with 16 or 17 locations and no margin. It happened as described. WHAT THE NUMBERS SAID ANYWAY — published, not binding: under both looser readings of 'the same location filters' (matched: at least 1 forward review; frozen_all: every frozen location), 11 of the 12 chains keep 15 or more locations, and the reading is HIT — the improving group's mean forward change is -0.0142 against -0.0289 for the declining group; the unweighted check agrees. Read that carefully before taking comfort in it: both groups fell. The chains we called improving did not improve — Subway (+0.0189) is the only one of the twelve with a positive forward change — they simply fell less than the decliners, which is what the entry actually asked (the prediction was relative and we said on 27 August that the bet was mostly about the decliners continuing to decline). It is consistent with the 14-day persistence relationship. It is not a HIT, and we do not get to count it as one: the reading we fixed in advance as binding voided, and a ledger in which the strict rule binds only when it flatters us would be worth nothing. CONTEXT ON THE FULL DATA (every location we hold, not just the frozen 437): strict VOID with per-chain numbers identical to the frozen sample — collection on these twelve chains was deliberately frozen from 28 August so that no location outside the sample could enter it, and none did; matched HIT (-0.0142 vs -0.0290); frozen_all HIT (-0.0142 vs -0.0284). CONTEXT WITHOUT THE 30 FOREIGN VENUES (annex #4, non-binding, computed by scripts/proof_xsec01_context_exclusion.py, commit 8b84288, committed before the grade): strict is VOID here too, and now on both sides — improving 3 of 6 (Wendy's drops from 14 to 12), declining 3 of 6, because In-N-Out Burger drops from 26 qualifying locations to 4: 22 of the 26 locations that carried In-N-Out's place in the declining group were Berlin burger restaurants that are not In-N-Out. The junk did not change the verdict. It did show that one of the twelve names in this entry was, on our own data, mostly not that chain — which is a data-hygiene failure we own; the country filter and location-quality flag announced in annex #4 will exclude such venues before any future sample is frozen. Matched without the 30: HIT, -0.0148 vs -0.0314. THE HONEST READ, in three lines. One: the void is ours — a qualifying rule sized for the pre-registration window and copied unchanged into a window half as long. Two: in every reading that produced a verdict, the ordering we predicted held; that is evidence about the relationship, not a graded hit, and it stays exactly that. Three: the sample was dirtier than the entry admitted, and we said so before grading, not after. WHAT CHANGES FOR XSEC-02, fixed now so it cannot be fitted to a result later: the location filter will be defined on the grading window itself, not copied from the pre-registration window; the frozen sample will pass a country filter and the location-quality flag before its ids are frozen; the grading code will be committed before the data exists, as it was here; and collection on the named chains will again be frozen for the life of the entry. Score line: a VOID counts as neither hit nor miss. Files: data/proof_xsec01_grade_final.json (binding and full-data context), data/proof_xsec01_context_exclusion_final.json (without the 30), data/proof_xsec01_foreign_locations.json (the 30, by name).
SHA-256 (immutable fields): 0101a914cbd4e76bdd9dce1610f882d61c2ec2b0fe99e78ef7e5f5fbfb8c6182