import%20marimo%0A%0A__generated_with%20%3D%20%220.25.0%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20imports()%3A%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20import%20ibis%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20pyarrow.parquet%20as%20pq%0A%0A%20%20%20%20from%20increment%20import%20Analysis%2C%20MetricSpec%0A%20%20%20%20from%20increment.tables%20import%20estimates_to_readout%2C%20readout_table%0A%0A%20%20%20%20DEFINITIONS%20%3D%20%22examples%2Frealistic_demo%2Fdefinitions%2F%22%0A%20%20%20%20EXPERIMENT%20%3D%20%22checkout_redesign%22%0A%20%20%20%20MOMENTS_PARQUET%20%3D%20Path.cwd()%20%2F%20%22increment_moments.parquet%22%0A%20%20%20%20WAREHOUSE%20%3D%20Path(%22examples%2Frealistic_demo%2Fwarehouse%22)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Analysis%2C%0A%20%20%20%20%20%20%20%20DEFINITIONS%2C%0A%20%20%20%20%20%20%20%20EXPERIMENT%2C%0A%20%20%20%20%20%20%20%20MOMENTS_PARQUET%2C%0A%20%20%20%20%20%20%20%20MetricSpec%2C%0A%20%20%20%20%20%20%20%20Path%2C%0A%20%20%20%20%20%20%20%20WAREHOUSE%2C%0A%20%20%20%20%20%20%20%20estimates_to_readout%2C%0A%20%20%20%20%20%20%20%20ibis%2C%0A%20%20%20%20%20%20%20%20mo%2C%0A%20%20%20%20%20%20%20%20pq%2C%0A%20%20%20%20%20%20%20%20readout_table%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20%23%20Register%20Markdown%20list%20preprocessors%20below%20superfences%20so%20fenced%20YAML%20is%0A%20%20%20%20%23%20protected%20before%20marimo's%20indentation%20passes%20inspect%20list-like%20lines.%0A%20%20%20%20%23%20Re-registering%20by%20name%20replaces%20the%20existing%20entries%20and%20is%20idempotent.%0A%20%20%20%20import%20marimo._output.md%20as%20_md_internals%0A%0A%20%20%20%20_md%2C%20_md_lock%20%3D%20_md_internals._get_markdown()%0A%20%20%20%20_md.preprocessors.register(_md.preprocessors%5B%22flexible_indent%22%5D%2C%20%22flexible_indent%22%2C%2024)%0A%20%20%20%20_md.preprocessors.register(%0A%20%20%20%20%20%20%20%20_md.preprocessors%5B%22breakless_lists_preproc%22%5D%2C%20%22breakless_lists_preproc%22%2C%2023%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Analyzing%20an%20Experiment%20From%20a%20Warehouse%0A%0A%20%20%20%20In%20this%20example%2C%20we%20look%20at%20a%20realistic%20checkout%20redesign%20A%2FB%20test%20and%20walk%20through%20measuring%20it.%0A%0A%20%20%20%20The%20experiment%20has%20one%20primary%20metric%2C%20two%20secondary%20metrics%2C%20and%20two%0A%20%20%20%20guardrails.%20The%20data%20lives%20in%20a%20normalized%20warehouse%2C%20so%20this%20starts%20in%0A%20%20%20%20the%20same%20place%20a%20production%20analysis%20would%3A%20with%20definitions%20for%20the%0A%20%20%20%20experiment%2C%20metrics%2C%20exposures%2C%20facts%2C%20and%20dimensions.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Looking%20at%20the%20semantic%20layer%0A%0A%20%20%20%20We%20use%20YAML%20as%20the%20source%20of%20truth%20for%20where%20data%20comes%20from%20and%20how%20the%0A%20%20%20%20experiment%20should%20be%20analyzed.%20The%20full%20set%20of%20definitions%20is%20below%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(DEFINITIONS%2C%20Path%2C%20mo)%3A%0A%20%20%20%20def%20_preview(fname)%3A%0A%20%20%20%20%20%20%20%20_yaml_text%20%3D%20(Path(DEFINITIONS)%20%2F%20fname).read_text()%0A%20%20%20%20%20%20%20%20return%20mo.md(f%22%60%60%60yaml%5Cn%7B_yaml_text%7D%5Cn%60%60%60%22)%0A%0A%20%20%20%20mo.accordion(%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Experiments%22%3A%20_preview(%22experiments.yaml%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Exposures%22%3A%20_preview(%22exposures.yaml%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Fact%20Sources%22%3A%20_preview(%22fact_sources.yaml%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Dim%20Sources%22%3A%20_preview(%22dim_sources.yaml%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Metrics%22%3A%20_preview(%22metrics.yaml%22)%2C%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Connecting%20to%20a%20warehouse%0A%0A%20%20%20%20DuckDB%20stands%20in%20for%20a%20production%20warehouse%20here.%20The%20semantic%20layer%20emits%0A%20%20%20%20SQL%20through%20ibis%2C%20so%20the%20analysis%20code%20stays%20the%20same%20when%20the%20connection%0A%20%20%20%20points%20at%20another%20supported%20backend.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ibis)%3A%0A%20%20%20%20%23%20Instantiate%20a%20local%20warehouse%20connection.%0A%20%20%20%20con%20%3D%20ibis.duckdb.connect()%0A%20%20%20%20return%20(con%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(WAREHOUSE)%3A%0A%20%20%20%20%23%20The%20warehouse%20is%20generated%2C%20never%20committed.%20Regenerate%20it%20when%20it%20is%0A%20%20%20%20%23%20missing%20or%20was%20produced%20by%20older%20generator%20semantics.%0A%20%20%20%20import%20importlib.util%20as%20_importlib_util%0A%20%20%20%20import%20json%20as%20_json%0A%0A%20%20%20%20_spec%20%3D%20_importlib_util.spec_from_file_location(%0A%20%20%20%20%20%20%20%20%22_demo_generate%22%2C%20%22examples%2Frealistic_demo%2Fgenerate.py%22%0A%20%20%20%20)%0A%20%20%20%20_generate_mod%20%3D%20_importlib_util.module_from_spec(_spec)%0A%20%20%20%20_spec.loader.exec_module(_generate_mod)%0A%0A%20%20%20%20_manifest_path%20%3D%20WAREHOUSE%20%2F%20%22manifest.json%22%0A%20%20%20%20warehouse_manifest%20%3D%20(%0A%20%20%20%20%20%20%20%20_json.loads(_manifest_path.read_text())%20if%20_manifest_path.is_file()%20else%20None%0A%20%20%20%20)%0A%20%20%20%20if%20(%0A%20%20%20%20%20%20%20%20warehouse_manifest%20is%20None%0A%20%20%20%20%20%20%20%20or%20warehouse_manifest.get(%22generator_version%22)%20!%3D%20_generate_mod.GENERATOR_VERSION%0A%20%20%20%20)%3A%0A%20%20%20%20%20%20%20%20WAREHOUSE.mkdir(parents%3DTrue%2C%20exist_ok%3DTrue)%0A%20%20%20%20%20%20%20%20_row_counts%20%3D%20_generate_mod.generate(%0A%20%20%20%20%20%20%20%20%20%20%20%20WAREHOUSE%2C%20partitions%3D2%2C%20users_per_partition%3D2000%2C%20seed%3D42%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20warehouse_manifest%20%3D%20_generate_mod.warehouse_manifest(%0A%20%20%20%20%20%20%20%20%20%20%20%20partitions%3D2%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20users_per_partition%3D2000%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20seed%3D42%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20row_counts%3D_row_counts%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20_manifest_path.write_text(_json.dumps(warehouse_manifest%2C%20indent%3D2)%20%2B%20%22%5Cn%22)%0A%0A%20%20%20%20%23%20This%20sentinel%20makes%20the%20file%20dependency%20explicit%20in%20marimo's%20DAG.%0A%20%20%20%20warehouse_ready%20%3D%20WAREHOUSE%0A%20%20%20%20return%20warehouse_manifest%2C%20warehouse_ready%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20warehouse_manifest)%3A%0A%20%20%20%20warehouse_summary%20%3D%20(%0A%20%20%20%20%20%20%20%20f%22The%20fixture%20contains%20%7Bwarehouse_manifest%5B'partitions'%5D%7D%20parquet%20%22%0A%20%20%20%20%20%20%20%20f%22partitions%20with%20%7Bwarehouse_manifest%5B'users_per_partition'%5D%3A%2C%7D%20%22%0A%20%20%20%20%20%20%20%20%22assigned%20users%20each.%5Cn%5Cn%22%0A%20%20%20%20%20%20%20%20%22%7C%20Warehouse%20relation%20%7C%20Rows%20%7C%5Cn%22%0A%20%20%20%20%20%20%20%20%22%7C---%7C---%3A%7C%5Cn%22%0A%20%20%20%20%20%20%20%20%2B%20%22%5Cn%22.join(%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22%7C%20%60%7Btable%7D%60%20%7C%20%7Bcount%3A%2C%7D%20%7C%22%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20table%2C%20count%20in%20warehouse_manifest%5B%22row_counts%22%5D.items()%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%20%20%20%20mo.md(warehouse_summary)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Analysis%2C%20DEFINITIONS%2C%20EXPERIMENT%2C%20con%2C%20warehouse_ready)%3A%0A%20%20%20%20assert%20(warehouse_ready%20%2F%20%22manifest.json%22).exists()%2C%20(%0A%20%20%20%20%20%20%20%20%22warehouse%20missing%3B%20run%20the%20generation%20cell%20above%20first%22%0A%20%20%20%20)%0A%20%20%20%20analysis%20%3D%20Analysis(%0A%20%20%20%20%20%20%20%20experiment_name%3DEXPERIMENT%2C%20definitions_path%3DDEFINITIONS%2C%20con%3Dcon%2C%20store%3D%22always%22%0A%20%20%20%20)%0A%20%20%20%20experiment%20%3D%20analysis.experiment%0A%20%20%20%20return%20analysis%2C%20experiment%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(experiment%2C%20mo)%3A%0A%20%20%20%20roles%20%3D%20experiment.plan.role_names()%0A%20%20%20%20primary%20%3D%20next(name%20for%20name%2C%20role%20in%20roles.items()%20if%20role%20%3D%3D%20%22primary%22)%0A%20%20%20%20secondaries%20%3D%20%5Bname%20for%20name%2C%20role%20in%20roles.items()%20if%20role%20%3D%3D%20%22secondary%22%5D%0A%20%20%20%20guardrails%20%3D%20%5Bname%20for%20name%2C%20role%20in%20roles.items()%20if%20role%20%3D%3D%20%22guardrail%22%5D%0A%20%20%20%20breakouts%20%3D%20%5Bbreakout.property%20for%20breakout%20in%20experiment.breakouts%5D%0A%20%20%20%20_inference%20%3D%20(%0A%20%20%20%20%20%20%20%20experiment.plan.inference.kind%0A%20%20%20%20%20%20%20%20if%20experiment.plan.inference%20is%20not%20None%0A%20%20%20%20%20%20%20%20else%20%22method-selected%20fixed%22%0A%20%20%20%20)%0A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%20Experiment%3A%20%7Bexperiment.name.replace(%22_%22%2C%20%22%20%22).title()%7D%0A%0A%20%20%20%20%20%20%20%20%7Bexperiment.description%7D%0A%0A%20%20%20%20%20%20%20%20%7C%20%7C%20%7C%0A%20%20%20%20%20%20%20%20%7C---%7C---%7C%0A%20%20%20%20%20%20%20%20%7C%20Window%20%7C%20%7Bexperiment.start%3A%25b%20%25d%2C%20%25Y%7D%20to%20%7Bexperiment.end%3A%25b%20%25d%2C%20%25Y%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20Unit%20%7C%20%60%7Bexperiment.unit%7D%60%20%7C%0A%20%20%20%20%20%20%20%20%7C%20Control%20%7C%20%60%7Bexperiment.control_group%7D%60%20%7C%0A%20%20%20%20%20%20%20%20%7C%20Primary%20%7C%20%60%7Bprimary%7D%60%20%7C%0A%20%20%20%20%20%20%20%20%7C%20Secondaries%20%7C%20%7B%22%2C%20%22.join(f%22%60%7Bname%7D%60%22%20for%20name%20in%20secondaries)%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20Guardrails%20%7C%20%7B%22%2C%20%22.join(f%22%60%7Bname%7D%60%22%20for%20name%20in%20guardrails)%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20Breakouts%20%7C%20%7B%22%2C%20%22.join(f%22%60%7Bname%7D%60%22%20for%20name%20in%20breakouts)%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20Inference%20%7C%20%60%7B_inference%7D%60%20%7C%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(analysis%2C%20mo)%3A%0A%20%20%20%20conversion_sql%20%3D%20analysis.summary_sql()%5B%22conversion_rate%22%5D%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%23%20Inspecting%20the%20SQL%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20The%20public%20SQL%20preview%20shows%20the%20warehouse%20reduction%20before%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20runs.%20Each%20metric%20produces%20the%20same%20small%20per-arm%20moments%20shape%0A%20%20%20%20%20%20%20%20%20%20%20%20consumed%20by%20the%20estimator.%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.accordion(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22SQL%20for%20the%20conversion_rate%20summary%22%3A%20mo.md(f%22%60%60%60sql%5Cn%7Bconversion_sql%7D%5Cn%60%60%60%22)%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(analysis%2C%20mo)%3A%0A%20%20%20%20srm_result%20%3D%20analysis.srm(expected%3D%7B%22control%22%3A%200.5%2C%20%22treatment%22%3A%200.5%7D)%0A%20%20%20%20srm_status%20%3D%20%22SRM%20detected%22%20if%20srm_result.is_srm%20else%20%22No%20SRM%20detected%22%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%20Checking%20the%20allocation%0A%0A%20%20%20%20%20%20%20%20The%20generator%20assigns%20users%2050%2F50.%20Reaching%20checkout%20is%20independent%20of%0A%20%20%20%20%20%20%20%20treatment%20in%20this%20fixture%2C%20so%20the%20enrolled%20population%20remains%20valid%0A%20%20%20%20%20%20%20%20for%20a%20sample-ratio%20check.%0A%0A%20%20%20%20%20%20%20%20**%7Bsrm_status%7D.**%0A%0A%20%20%20%20%20%20%20%20%7C%20Arm%20%7C%20Enrolled%20units%20%7C%0A%20%20%20%20%20%20%20%20%7C---%7C---%3A%7C%0A%20%20%20%20%20%20%20%20%7C%20control%20%7C%20%7Bsrm_result.observed%5B%22control%22%5D%3A%2C%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20treatment%20%7C%20%7Bsrm_result.observed%5B%22treatment%22%5D%3A%2C%7D%20%7C%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Running%20the%20analysis%0A%0A%20%20%20%20One%20call%20runs%20every%20metric%20named%20in%20the%20experiment%20plan.%20The%20plan%20also%0A%20%20%20%20supplies%20metric%20roles%2C%20fixed-horizon%20inference%2C%20and%20the%20multiplicity%20policy%0A%20%20%20%20used%20by%20downstream%20views.%0A%0A%20%20%20%20With%20%60store%3D%22always%22%60%2C%20each%20readout%20builds%20fresh%20materialized%20tables.%0A%20%20%20%20Metrics%20share%20those%20tables%20within%20the%20call%3B%20later%20headline%2C%20breakout%2C%0A%20%20%20%20and%20monitoring%20calls%20rebuild%20them%20to%20pick%20up%20warehouse%20corrections.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis)%3A%0A%20%20%20%20%23%20This%20readout%20materializes%20once%20for%20all%20declared%20metrics.%0A%20%20%20%20estimates%20%3D%20analysis.run()%0A%20%20%20%20return%20(estimates%2C)%0A%0A%0A%40app.cell%0Adef%20_(estimates%2C%20estimates_to_readout%2C%20readout_table)%3A%0A%20%20%20%20headline_table%20%3D%20readout_table(%0A%20%20%20%20%20%20%20%20estimates_to_readout(estimates)%2C%0A%20%20%20%20%20%20%20%20title%3D%22Checkout%20Redesign%3A%20Headline%20Readout%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D%22All%205%20declared%20metrics%2C%20assigned%20population%2C%20fixed-horizon%20intervals%22%2C%0A%20%20%20%20)%0A%20%20%20%20headline_table%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Exploring%20the%20data%20with%20breakouts%0A%0A%20%20%20%20We%20can%20break%20the%20result%20out%20by%20segment%20or%20follow%20it%20over%20time.%20Both%20views%0A%20%20%20%20are%20useful%2C%20but%20they%20also%20create%20more%20chances%20to%20read%20noise%20as%20signal.%20The%0A%20%20%20%20experiment%20plan%20supplies%20the%20correction%20for%20the%20declared%20breakout%20views.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis%2C%20estimates_to_readout%2C%20readout_table)%3A%0A%20%20%20%20breakout_estimates%20%3D%20analysis.run_breakout()%0A%20%20%20%20country_breakout_estimates%20%3D%20%5B%0A%20%20%20%20%20%20%20%20estimate%0A%20%20%20%20%20%20%20%20for%20estimate%20in%20breakout_estimates%0A%20%20%20%20%20%20%20%20if%20estimate.metric%20%3D%3D%20%22conversion_rate%22%20and%20estimate.dimension%20%3D%3D%20%22country%22%0A%20%20%20%20%5D%0A%0A%20%20%20%20breakout_table%20%3D%20readout_table(%0A%20%20%20%20%20%20%20%20estimates_to_readout(country_breakout_estimates)%2C%0A%20%20%20%20%20%20%20%20title%3D%22Checkout%20Redesign%3A%20Breakouts%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D%22conversion_rate%2C%20by%20country%22%2C%0A%20%20%20%20%20%20%20%20nest_by%3D%22segment%22%2C%0A%20%20%20%20)%0A%20%20%20%20breakout_table%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis%2C%20estimates%2C%20estimates_to_readout%2C%20readout_table)%3A%0A%20%20%20%20daily_estimates%20%3D%20analysis.run_asof_lift(%0A%20%20%20%20%20%20%20%20metrics%3D%5B%22conversion_rate%22%5D%2C%0A%20%20%20%20)%0A%0A%20%20%20%20trend_table%20%3D%20readout_table(%0A%20%20%20%20%20%20%20%20estimates_to_readout(%5Be%20for%20e%20in%20estimates%20if%20e.metric%20%3D%3D%20%22conversion_rate%22%5D)%2C%0A%20%20%20%20%20%20%20%20title%3D%22Checkout%20Redesign%3A%20conversion_rate%20over%20time%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D%22Daily%20lift%20trajectory%22%2C%0A%20%20%20%20%20%20%20%20trend%3Dlist(daily_estimates)%2C%0A%20%20%20%20)%0A%20%20%20%20trend_table%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Exporting%20moments%20for%20reuse%0A%0A%20%20%20%20%60Analysis.export()%60%20writes%20additive%20moments%2C%20not%20event%20rows.%20Each%20row%0A%20%20%20%20carries%20a%20%60moments_format%3D7%60%20version%20stamp%20and%20the%20complete%20compiled%0A%20%20%20%20decision%20plan%20-%20methods%2C%20roles%2C%20inference%2C%20and%20view%20policies%20travel%0A%20%20%20%20with%20the%20evidence.%20A%20second%20analysis%20can%20load%20that%20compact%20cube%20and%0A%20%20%20%20reproduce%20the%20headline%20estimates%20without%20a%20warehouse%20connection%3B%0A%20%20%20%20%60from_moments%60%20validates%20the%20embedded%20plan%20and%20refuses%20legacy%20or%0A%20%20%20%20partial%20exports%2C%20so%20a%20rehydrated%20readout%20cannot%20silently%20decide%20under%0A%20%20%20%20a%20different%20procedure.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(MOMENTS_PARQUET%2C%20analysis%2C%20pq)%3A%0A%20%20%20%20analysis.export(MOMENTS_PARQUET)%0A%20%20%20%20exported_moments%20%3D%20pq.read_table(MOMENTS_PARQUET).to_pylist()%0A%20%20%20%20return%20(exported_moments%2C)%0A%0A%0A%40app.cell%0Adef%20_(Analysis%2C%20MetricSpec%2C%20experiment%2C%20exported_moments)%3A%0A%20%20%20%20moment_metrics%20%3D%20%5B%0A%20%20%20%20%20%20%20%20MetricSpec(%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22conversion_rate%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20type%3D%22conversion%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20window_days%3D14%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20preferred_direction%3D%22increase%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20MetricSpec(%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22revenue_per_user%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20window_days%3D14%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20preferred_direction%3D%22increase%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20MetricSpec(%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22average_order_value%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20type%3D%22ratio%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20numerator%3D%22revenue%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20denominator%3D%22orders%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20window_days%3D14%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20preferred_direction%3D%22increase%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20MetricSpec(%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22d7_retention%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20type%3D%22retention%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20threshold_days%3D(7%2C%2014)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20preferred_direction%3D%22increase%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20MetricSpec(%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22checkout_latency_ms%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20type%3D%22ratio%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20numerator%3D%22load_time%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20denominator%3D%22events%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20window_days%3D14%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20preferred_direction%3D%22decrease%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%5D%0A%20%20%20%20rehydrated_analysis%20%3D%20Analysis.from_moments(%0A%20%20%20%20%20%20%20%20exported_moments%2C%0A%20%20%20%20%20%20%20%20metrics%3Dmoment_metrics%2C%0A%20%20%20%20%20%20%20%20control%3Dexperiment.control_group%2C%0A%20%20%20%20%20%20%20%20experiment_id%3Dexperiment.name%2C%0A%20%20%20%20)%0A%20%20%20%20rehydrated_estimates%20%3D%20rehydrated_analysis.run()%0A%20%20%20%20return%20(rehydrated_estimates%2C)%0A%0A%0A%40app.cell%0Adef%20_(estimates%2C%20estimates_to_readout%2C%20readout_table%2C%20rehydrated_estimates)%3A%0A%20%20%20%20warehouse_lifts%20%3D%20%7B%0A%20%20%20%20%20%20%20%20(estimate.metric%2C%20estimate.group_id)%3A%20estimate.lift.value%20for%20estimate%20in%20estimates%0A%20%20%20%20%7D%0A%20%20%20%20rehydrated_lifts%20%3D%20%7B%0A%20%20%20%20%20%20%20%20(estimate.metric%2C%20estimate.group_id)%3A%20estimate.lift.value%0A%20%20%20%20%20%20%20%20for%20estimate%20in%20rehydrated_estimates%0A%20%20%20%20%7D%0A%20%20%20%20assert%20rehydrated_lifts.keys()%20%3D%3D%20warehouse_lifts.keys()%0A%20%20%20%20max_lift_difference%20%3D%20max(%0A%20%20%20%20%20%20%20%20abs(rehydrated_lifts%5Bkey%5D%20-%20value)%20for%20key%2C%20value%20in%20warehouse_lifts.items()%0A%20%20%20%20)%0A%20%20%20%20assert%20max_lift_difference%20%3C%201e-12%0A%0A%20%20%20%20rehydrated_table%20%3D%20readout_table(%0A%20%20%20%20%20%20%20%20estimates_to_readout(rehydrated_estimates)%2C%0A%20%20%20%20%20%20%20%20title%3D%22Checkout%20Redesign%3A%20Rehydrated%20Readout%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D%22The%20same%20five%20metrics%2C%20loaded%20from%20additive%20moments%22%2C%0A%20%20%20%20)%0A%20%20%20%20rehydrated_table%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Where%20to%20go%20next%0A%0A%20%20%20%20The%20%5Bdata%20model%20guide%5D(..%2Fguides%2Fdata-model%2F)%20opens%20up%20the%20warehouse%20and%0A%20%20%20%20query%20pipeline.%20The%20%5Bdataframe%20tutorial%5D(analysis_from_a_dataframe.html)%0A%20%20%20%20shows%20the%20same%20analysis%20facade%20when%20the%20input%20is%20already%20one%20row%20per%20unit%0A%20%20%20%20or%20a%20unit-day%20panel.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
9e292bd74bc431b56248fe722ee27e56