test-demoprep / docs /MIGRATION.md
mikeboone's picture
Wire single blueprint pipeline; fix engine formula fidelity + insight direction
3993fe3
|
Raw
History Blame Contribute Delete
6.73 kB

A newer version of the Gradio SDK is available: 6.26.0

Upgrade

Blueprint Rewrite β€” Migration Notes

What changed conceptually

Old: LLM does a thin extraction -> keyword router picks a scenario family -> Python templates with hardcoded value lists fill the gaps -> specialized generators for the verticals we've hand-tuned.

New: one rich LLM call authors a complete DemoBlueprint (all semantics: real domain nouns, distributions, formulas, seasonality, and 3-5 planted insights with the exact Spotter questions that reveal them) -> one generic deterministic BlueprintEngine executes any blueprint -> a validator proves each planted insight is demo-visible in the actual rows, and a cheap boost-and-regenerate loop fixes weak ones at the contract level.

The LLM decides what the data means; deterministic code decides what the rows are. No vertical-specific code anywhere downstream of the blueprint.

New files

File Role
demoprep_app/scenario/blueprint.py DemoBlueprint dataclasses + problems() validation (repair messages are written for the LLM)
demoprep_app/scenario/blueprint_author.py The one LLM call. The user's request is quoted verbatim as highest authority; few-shot examples replace scenario families. Up to 2 repair rounds.
demoprep_app/scenario/directives.py Deterministic extraction + enforcement of explicit user schema instructions (named tables, prohibitions). Direct fix for the McKesson routing failure.
demoprep_app/dataset/engine.py The only generator. Deterministic given (blueprint, seed). Also decides date-dimension-vs-inline-date per blueprint, resolving the open date-modeling question.
demoprep_app/dataset/validator.py Integrity + formula + planted-insight checks over the in-memory bundle
demoprep_app/pipeline/build_demo.py THE pipeline (there is exactly one): author -> generate -> validate -> boost loop -> DDL. Canonical entry build_demo(); dataset_first.py remains only as a deprecated import shim during cutover.
SINGLE_PIPELINE.md Surgery guide for chat_interface.py: delete the data_generation_mode/DEMOPREP_DATASET_FIRST fork (which currently defaults to legacy), the silent "falling back to DDL-first" branch, the legacy LLM-DDL stage, and the LegitData population path.
tests/test_blueprint_pipeline.py LLM-free smoke test (run: PYTHONPATH=. python tests/test_blueprint_pipeline.py)
tests/test_mckesson_regression.py Replays the real McKesson failure: extracts directives from the actual prompts, rejects the exact FACILITIES/SERVICE_LINES output the old app produced, and builds the correct 6-table / 2-fact demo.

Delete (no longer imported)

  • demoprep_app/scenario/selector.py β€” keyword routing
  • demoprep_app/scenario/extractor.py β€” thin extraction
  • demoprep_app/scenario/families.py β€” templates-as-code (their knowledge now lives as few-shot JSON in blueprint_author.py; port any families you find valuable as additional compact examples)
  • demoprep_app/dataset/generators/ β€” all of it: base.py, router.py, retail_sales.py, saas_sales.py, template_generator.py

Untouched

  • demoprep_app/dataset/contracts.py (DatasetBundle/Table/Column)
  • demoprep_app/ddl/ DatasetDdlCompiler
  • demoprep_app/integrations/snowflake.py populate_dataset_bundle
  • chat_interface.py call site (signature preserved; use_llm_contract kept as a no-op arg)

Two files in this package are test stubs only β€” replace with your real modules when dropping in: demoprep_app/scenario/contract.py and demoprep_app/ddl/__init__.py. If your real ScenarioContract has different field names, adjust _compat_scenario() in engine.py (one function, ~30 lines β€” the only place the two worlds touch).

The McKesson failure, specifically

The 2026-07 incident (custom prompt naming 6 exact tables -> keyword-routed to the healthcare_operations family -> FACILITIES / SERVICE_LINES / PAYERS / REGIONS / HEALTHCARE_OPERATIONS) is now impossible three ways:

  1. selector.py and families.py are deleted β€” there is no keyword router and no hardcoded table set to route into.
  2. The author prompt quotes the user's request verbatim as the highest authority, with an explicit warning against modeling the industry's generic operations instead of the company's actual business.
  3. directives.py extracts named tables (DIM_*/FACT_* tokens) and prohibitions ("do not create facilities...", "not a hospital operations demo") from the user's own words and enforces them deterministically. Violations feed the LLM repair loop; any that survive retries abort the build with USER DIRECTIVE VIOLATED β€” the wrong story can never silently ship. chat_interface.py should pass the raw custom prompt as user_request= (falls back to use_case otherwise).

Blueprints also now support 1-3 fact tables over shared dimensions (facts: [FactSpec]), because real custom specs like McKesson's have two. Measure names must be unique across facts; insights resolve to the fact owning their measure; each fact can name its date column (e.g. MONTH_DATE).

Behavior changes to be aware of

  1. Fails loudly. No silent fallback to templates. If the LLM can't produce a valid blueprint after repair rounds, the build raises with the validation report. A template demo is worse than a clear error you can retry.
  2. Planted insights flow downstream. bundle.scenario.metadata["planted_insights"] carries id/headline/spotter_question/expected_finding β€” wire these into the liveboard question generator and Spotter Viz story so the demo narrative and the data are guaranteed to agree. That's the Demo to Win payoff.
  3. Date dimension is now a per-scenario LLM decision (blueprint field date.include_date_dimension, forced true when fiscal_or_custom_calendar is set) instead of always-emitted. Matches the design guidance in the architecture doc.
  4. performance and insight magnitude compound. A store with performance 0.8 that is also a 0.75 laggard insight lands around 0.6x. The validator only requires half the promised effect to realize, so this is safe, but the effect can be stronger than the headline claims. If that bothers you, have the author prompt forbid overlapping the two.
  5. Determinism. Seed derives from company_url|use_case, so rebuilding the same demo produces the same data β€” good for the e2e quality harness.

Suggested follow-ups (not included)

  • Port your best families.py entries into 2-3 more few-shot examples.
  • Feed planted_insights into liveboard_creator.py question generation.
  • e2e harness: assert build.validation.passed and surface build.warnings.