"""Freeze an outcome-hidden description pilot before new outcome analyses."""
import hashlib
from common import *
d,t=load()
pool=d[d.build&d.period.ne('other')]
rows=[]
for family in ['deck','auto','action','tower','other']:
    for period in ['2025','2026_H1','2026_JulAug']:
        x=pool[pool.pilot_family.eq(family)&pool.period.eq(period)]
        take=x.sample(n=4,random_state=690621).sort_index()
        for a in take.itertuples():
            rows.append(dict(appid=a.appid,name=a.name,family=family,period=period,
                             short_description=a.short_description,description=a.description))
save_json('pilot_blind.json',rows)
save_json('specification.json',dict(
    snapshot='2026-09-05',network='Offline only; source files unchanged',
    source='Previous prepared catalog and frozen build classifier, not older research logs',
    branch1='Equivalent January-August 2025 and 2026 cohorts. Genre overlaps shown explicitly and fractional attribution used for additive totals. Within-signature build-share change separated from catalog-volume/composition change with symmetric decomposition.',
    branch2='2025, H1 2026 and July-August 2026 separately. Existing paid build pool and all eligible paid deck-tag games; volume, conditional positivity, joint outcomes. Hybrid tags are overlapping observable positioning, not verified gameplay.',
    branch3=dict(n=60,seed=690621,sampling='4 random strict builds per period per exclusive family: deck > auto > action > tower > other. Balanced across 15 strata, not representative of market prevalence. Names visible, outcomes and price hidden; some names may already be familiar.',
        rule='Concrete configuration rule: description explains at least one specific dependency, transformation, positional effect, composition threshold, or configuration constraint that gives the reader a reason to choose a component in one setup rather than another. Generic synergies, different playstyles, item counts, and mere lists of features are insufficient. Ordinary tactical timing alone is insufficient. Unknown is not absence in the game.',
        labels='concrete, generic, unclear; record rule types and paraphrased supporting evidence. Description evidence only, not verified depth. Freeze labels before joining outcomes.',
        decision='Only attempt a larger mechanism screen if this pilot provides sufficiently clear, repeatable textual distinctions; otherwise deliver a case map and refrain from a market-wide effect estimate.'),
    pilot_sha256=hashlib.sha256((R/'pilot_blind.json').read_bytes()).hexdigest()))
print('Frozen pilot: 60 descriptions, without review counts or prices.')
