churnkit 1.3.2a2__tar.gz → 1.3.2a3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/PKG-INFO +1 -1
  2. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/theme.css +1 -1
  3. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/pyproject.toml +1 -1
  4. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/__init__.py +1 -1
  5. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s_c04_batch_inference.py +59 -37
  6. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scoring/batch_inference.py +68 -8
  7. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/.gitignore +0 -0
  8. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/LICENSE +0 -0
  9. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/README.md +0 -0
  10. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/__init__.py +0 -0
  11. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/accounts_view.py +0 -0
  12. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/archetype_view.py +0 -0
  13. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/archetypes_view.py +0 -0
  14. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/auth.py +0 -0
  15. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/config.py +0 -0
  16. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/customer_profile.py +0 -0
  17. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/data.py +0 -0
  18. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/default_profile.css +0 -0
  19. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/default_profile.html +0 -0
  20. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/masthead.py +0 -0
  21. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/playbooks_view.py +0 -0
  22. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/state.py +0 -0
  23. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/template.py +0 -0
  24. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/apps/databricks_app/src/treemap.py +0 -0
  25. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/causal_notebooks/_diagnostic_scoring_probe.py +0 -0
  26. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/causal_notebooks/c01_publish_definitions.ipynb +0 -0
  27. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/causal_notebooks/c02_archetype_derivation.ipynb +0 -0
  28. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/causal_notebooks/c03_approval_gate.ipynb +0 -0
  29. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/causal_notebooks/c04_batch_inference.ipynb +0 -0
  30. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/causal_notebooks/c05_snapshot_and_dashboard.ipynb +0 -0
  31. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/constraints/.gitkeep +0 -0
  32. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/-1_parity_contract.ipynb +0 -0
  33. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/-1_sample_datasets.ipynb +0 -0
  34. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/00_start_here.ipynb +0 -0
  35. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/01_data_discovery.ipynb +0 -0
  36. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/01a_a_temporal_text_deep_dive.ipynb +0 -0
  37. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/01a_temporal_deep_dive.ipynb +0 -0
  38. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/01b_temporal_quality.ipynb +0 -0
  39. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/01c_temporal_patterns.ipynb +0 -0
  40. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/01d_event_aggregation.ipynb +0 -0
  41. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/02_source_integrity.ipynb +0 -0
  42. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/03_dataset_merge.ipynb +0 -0
  43. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/04_column_deep_dive.ipynb +0 -0
  44. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/04a_text_columns_deep_dive.ipynb +0 -0
  45. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/05_relationship_analysis.ipynb +0 -0
  46. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/06_feature_opportunities.ipynb +0 -0
  47. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/07_modeling_readiness.ipynb +0 -0
  48. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/08_baseline_experiments.ipynb +0 -0
  49. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/09_business_alignment.ipynb +0 -0
  50. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/10_spec_generation.ipynb +0 -0
  51. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/11_scoring_validation.ipynb +0 -0
  52. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/exploration_notebooks/12_view_documentation.ipynb +0 -0
  53. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/.claude/settings.local.json +0 -0
  54. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/README.md +0 -0
  55. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/build_framework_phase_map.py +0 -0
  56. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/data/create_snapshot.py +0 -0
  57. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/data/generate_edi_ticketing_dataset.py +0 -0
  58. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/data/generate_retail_dataset.py +0 -0
  59. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/data/generate_test_data.py +0 -0
  60. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/data/migrate_parquet_to_delta.py +0 -0
  61. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/data/migrate_to_temporal.py +0 -0
  62. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/databricks/build_wheel.sh +0 -0
  63. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/databricks/capture_runtime.py +0 -0
  64. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/databricks/dbr_init.sh +0 -0
  65. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/databricks/deploy_dev.py +0 -0
  66. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/databricks/generate_constraints.py +0 -0
  67. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/databricks/notebook_setup.py +0 -0
  68. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/experiments/capture_notebook_outputs.py +0 -0
  69. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/experiments/cell_profiling.py +0 -0
  70. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/experiments/compare_exploration_runs.py +0 -0
  71. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/experiments/compare_versions.sh +0 -0
  72. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/experiments/patch_dataset_config.py +0 -0
  73. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/generate_requirements.py +0 -0
  74. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/build_causal_notebooks.py +0 -0
  75. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/clean_notebook_outputs.py +0 -0
  76. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/export_tutorial_html.py +0 -0
  77. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/init_project.py +0 -0
  78. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/migrate_notebook_cell_ids.py +0 -0
  79. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/plotly_image_preprocessor.py +0 -0
  80. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/run_exploration.py +0 -0
  81. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/sync_notebooks.py +0 -0
  82. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/tag_framework_cells.py +0 -0
  83. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/tag_markdown_cells.py +0 -0
  84. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/notebooks/test_notebooks.py +0 -0
  85. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/release.sh +0 -0
  86. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/seed_playbooks_volume.py +0 -0
  87. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/templates/tutorial_html/conf.json +0 -0
  88. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/templates/tutorial_html/index.html.j2 +0 -0
  89. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/scripts/update_notebook_paths.py +0 -0
  90. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/__init__.py +0 -0
  91. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/__init__.py +0 -0
  92. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/active_dataset_store.py +0 -0
  93. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/analysis_context.py +0 -0
  94. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/column_describer.py +0 -0
  95. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/dataset_fingerprinter.py +0 -0
  96. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/entity_timestamp_deriver.py +0 -0
  97. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/exploration_manager.py +0 -0
  98. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/explorer.py +0 -0
  99. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/field_availability_audit.py +0 -0
  100. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/findings.py +0 -0
  101. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/intent_defaults.py +0 -0
  102. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/key_resolver.py +0 -0
  103. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/layered_recommendations.py +0 -0
  104. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/objective_support_communicator.py +0 -0
  105. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/prediction_objective_detector.py +0 -0
  106. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/project_context.py +0 -0
  107. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/recommendation_builder.py +0 -0
  108. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/recommendations.py +0 -0
  109. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/run_namespace.py +0 -0
  110. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/sampling.py +0 -0
  111. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/schema_report.py +0 -0
  112. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/service_unit_detector.py +0 -0
  113. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/session.py +0 -0
  114. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/skip_logic.py +0 -0
  115. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/auto_explorer/snapshot_grid.py +0 -0
  116. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/business/__init__.py +0 -0
  117. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/business/ab_test_designer.py +0 -0
  118. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/business/fairness_analyzer.py +0 -0
  119. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/business/intervention_matcher.py +0 -0
  120. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/business/ratio_features.py +0 -0
  121. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/business/report_generator.py +0 -0
  122. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/business/risk_profile.py +0 -0
  123. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/business/roi_analyzer.py +0 -0
  124. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/__init__.py +0 -0
  125. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/calibration_analyzer.py +0 -0
  126. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/cv_analyzer.py +0 -0
  127. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/error_analyzer.py +0 -0
  128. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/exploration_ledger.py +0 -0
  129. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/feature_provenance.py +0 -0
  130. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/feature_stability.py +0 -0
  131. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/leakage_detector.py +0 -0
  132. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/model_diagnostics_report.py +0 -0
  133. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/noise_tester.py +0 -0
  134. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/overfitting_analyzer.py +0 -0
  135. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/parity_report.py +0 -0
  136. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/diagnostics/segment_analyzer.py +0 -0
  137. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/discovery/__init__.py +0 -0
  138. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/discovery/config_generator.py +0 -0
  139. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/discovery/discovery_flow.py +0 -0
  140. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/discovery/type_inferencer.py +0 -0
  141. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/interpretability/__init__.py +0 -0
  142. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/interpretability/cohort_analyzer.py +0 -0
  143. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/interpretability/counterfactual.py +0 -0
  144. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/interpretability/individual_explainer.py +0 -0
  145. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/interpretability/pdp_generator.py +0 -0
  146. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/interpretability/shap_explainer.py +0 -0
  147. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/jupyter_save_hook.py +0 -0
  148. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/notebook_html_exporter.py +0 -0
  149. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/notebook_progress.py +0 -0
  150. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/plotly_preprocessor.py +0 -0
  151. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/__init__.py +0 -0
  152. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/base.py +0 -0
  153. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/cleaning/__init__.py +0 -0
  154. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/cleaning/consistency.py +0 -0
  155. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/cleaning/deduplicate.py +0 -0
  156. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/cleaning/impute.py +0 -0
  157. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/cleaning/outlier.py +0 -0
  158. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/datetime/__init__.py +0 -0
  159. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/datetime/extract.py +0 -0
  160. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/encoding/__init__.py +0 -0
  161. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/encoding/categorical.py +0 -0
  162. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/pipeline.py +0 -0
  163. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/registry.py +0 -0
  164. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/selection/__init__.py +0 -0
  165. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/selection/drop_column.py +0 -0
  166. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/transform/__init__.py +0 -0
  167. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/transform/power.py +0 -0
  168. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/recommendations/transform/scale.py +0 -0
  169. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/visualization/__init__.py +0 -0
  170. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/visualization/attention_scorer.py +0 -0
  171. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/visualization/chart_builder.py +0 -0
  172. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/visualization/column_paginator.py +0 -0
  173. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/visualization/console.py +0 -0
  174. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/visualization/display.py +0 -0
  175. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/analysis/visualization/number_formatter.py +0 -0
  176. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/artifacts/__init__.py +0 -0
  177. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/artifacts/fit_artifact_registry.py +0 -0
  178. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/cli.py +0 -0
  179. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/__init__.py +0 -0
  180. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/__init__.py +0 -0
  181. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/bulk_profiling.py +0 -0
  182. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/cell_profiling_hooks.py +0 -0
  183. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/detection.py +0 -0
  184. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/ops.py +0 -0
  185. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/pandas_backend.py +0 -0
  186. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/remote_path.py +0 -0
  187. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/spark_backend.py +0 -0
  188. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/compat/timing.py +0 -0
  189. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/__init__.py +0 -0
  190. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/base.py +0 -0
  191. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/__init__.py +0 -0
  192. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/deployer.py +0 -0
  193. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/explainer.py +0 -0
  194. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/feature_eng.py +0 -0
  195. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/ingester.py +0 -0
  196. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/profiler.py +0 -0
  197. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/trainer.py +0 -0
  198. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/transformer.py +0 -0
  199. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/components/validator.py +0 -0
  200. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/enums.py +0 -0
  201. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/orchestrator.py +0 -0
  202. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/components/registry.py +0 -0
  203. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/config/__init__.py +0 -0
  204. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/config/column_config.py +0 -0
  205. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/config/experiments.py +0 -0
  206. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/config/pipeline_config.py +0 -0
  207. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/config/source_config.py +0 -0
  208. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/naming.py +0 -0
  209. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/utils/__init__.py +0 -0
  210. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/utils/leakage.py +0 -0
  211. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/utils/severity.py +0 -0
  212. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/core/utils/statistics.py +0 -0
  213. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/__init__.py +0 -0
  214. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/__init__.py +0 -0
  215. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/base.py +0 -0
  216. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/cell_builder.py +0 -0
  217. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/config.py +0 -0
  218. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/databricks_generator.py +0 -0
  219. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/local_generator.py +0 -0
  220. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/project_init.py +0 -0
  221. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/runner.py +0 -0
  222. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/scoring_replay.py +0 -0
  223. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/script_generator.py +0 -0
  224. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/__init__.py +0 -0
  225. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/base_stage.py +0 -0
  226. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/causal_setup_cell.py +0 -0
  227. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s01_ingestion.py +0 -0
  228. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s02_profiling.py +0 -0
  229. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s03_cleaning.py +0 -0
  230. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s04_transformation.py +0 -0
  231. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s05_feature_engineering.py +0 -0
  232. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s06_feature_selection.py +0 -0
  233. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s07_model_training.py +0 -0
  234. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s08_deployment.py +0 -0
  235. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s09_monitoring.py +0 -0
  236. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s10_batch_inference.py +0 -0
  237. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s11_feature_store.py +0 -0
  238. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s_c01_publish_definitions.py +0 -0
  239. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s_c02_archetype_derivation.py +0 -0
  240. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s_c03_approval_gate.py +0 -0
  241. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_generator/stages/s_c05_snapshot_and_dashboard.py +0 -0
  242. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_merge/__init__.py +0 -0
  243. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_merge/cli.py +0 -0
  244. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_merge/config_merger.py +0 -0
  245. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_merge/config_parser.py +0 -0
  246. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_merge/conflict.py +0 -0
  247. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_merge/merge_engine.py +0 -0
  248. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_merge/merge_report.py +0 -0
  249. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_sync/__init__.py +0 -0
  250. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_sync/cell_id_standardizer.py +0 -0
  251. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_sync/cell_types.py +0 -0
  252. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_sync/cli.py +0 -0
  253. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_sync/sync_engine.py +0 -0
  254. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/notebook_sync/sync_report.py +0 -0
  255. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/orchestration/__init__.py +0 -0
  256. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/orchestration/code_generator.py +0 -0
  257. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/orchestration/context.py +0 -0
  258. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/orchestration/data_materializer.py +0 -0
  259. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/orchestration/databricks_exporter.py +0 -0
  260. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/orchestration/doc_generator.py +0 -0
  261. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/__init__.py +0 -0
  262. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/databricks_generator.py +0 -0
  263. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/databricks_renderer.py +0 -0
  264. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/exploration_generator.py +0 -0
  265. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/findings_parser.py +0 -0
  266. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/generation_manifest.py +0 -0
  267. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/generator.py +0 -0
  268. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/gold_transform_applicator.py +0 -0
  269. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/llm_docs_generator.py +0 -0
  270. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/models.py +0 -0
  271. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/override_merge.py +0 -0
  272. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/protocols.py +0 -0
  273. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/renderer.py +0 -0
  274. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/pipeline_generator/user_extensions_emitter.py +0 -0
  275. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/spec_generator/__init__.py +0 -0
  276. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/generators/spec_generator/mlflow_pipeline_generator.py +0 -0
  277. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/__init__.py +0 -0
  278. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/__init__.py +0 -0
  279. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/base.py +0 -0
  280. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/factory.py +0 -0
  281. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/feature_store/__init__.py +0 -0
  282. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/feature_store/base.py +0 -0
  283. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/feature_store/databricks.py +0 -0
  284. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/feature_store/feast_adapter.py +0 -0
  285. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/feature_store/local.py +0 -0
  286. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/mlflow/__init__.py +0 -0
  287. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/mlflow/base.py +0 -0
  288. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/mlflow/databricks.py +0 -0
  289. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/mlflow/experiment_tracker.py +0 -0
  290. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/mlflow/local.py +0 -0
  291. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/storage/__init__.py +0 -0
  292. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/storage/base.py +0 -0
  293. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/storage/databricks.py +0 -0
  294. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/adapters/storage/local.py +0 -0
  295. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/databricks_init.py +0 -0
  296. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/databricks_job_capture.py +0 -0
  297. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/feature_store/__init__.py +0 -0
  298. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/feature_store/definitions.py +0 -0
  299. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/feature_store/manager.py +0 -0
  300. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/feature_store/registry.py +0 -0
  301. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/iteration/__init__.py +0 -0
  302. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/iteration/context.py +0 -0
  303. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/iteration/feedback_collector.py +0 -0
  304. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/iteration/orchestrator.py +0 -0
  305. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/iteration/recommendation_tracker.py +0 -0
  306. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/iteration/signals.py +0 -0
  307. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/llm_context/__init__.py +0 -0
  308. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/llm_context/context_builder.py +0 -0
  309. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/llm_context/prompts.py +0 -0
  310. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/requirements_generator.py +0 -0
  311. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/streaming/__init__.py +0 -0
  312. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/streaming/batch_integration.py +0 -0
  313. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/streaming/early_warning_model.py +0 -0
  314. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/streaming/event_schema.py +0 -0
  315. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/streaming/online_store_writer.py +0 -0
  316. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/streaming/realtime_scorer.py +0 -0
  317. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/streaming/trigger_engine.py +0 -0
  318. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/integrations/streaming/window_aggregator.py +0 -0
  319. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/__init__.py +0 -0
  320. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/audit.py +0 -0
  321. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/decorator.py +0 -0
  322. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/exploration_scan.py +0 -0
  323. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/gaps.py +0 -0
  324. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/kinds.py +0 -0
  325. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/manifest.py +0 -0
  326. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/production_scan.py +0 -0
  327. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/schedule.py +0 -0
  328. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/parity/trace.py +0 -0
  329. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/__init__.py +0 -0
  330. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/api.py +0 -0
  331. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/dataset_resolution.py +0 -0
  332. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/decorator.py +0 -0
  333. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/flags.py +0 -0
  334. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/harvest.py +0 -0
  335. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/logging.py +0 -0
  336. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/persistence.py +0 -0
  337. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/registry.py +0 -0
  338. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/replay.py +0 -0
  339. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/summary.py +0 -0
  340. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/runtime/validation.py +0 -0
  341. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/__init__.py +0 -0
  342. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/__init__.py +0 -0
  343. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/approval_gate.py +0 -0
  344. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/clusterer.py +0 -0
  345. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/column_descriptions_writer.py +0 -0
  346. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/dashboard_profile_override.py +0 -0
  347. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/dashboard_views.py +0 -0
  348. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/delta_writer.py +0 -0
  349. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/derivation.py +0 -0
  350. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/feature_meta_writer.py +0 -0
  351. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/__init__.py +0 -0
  352. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/archetype_context.py +0 -0
  353. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/business_phrase.py +0 -0
  354. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/discovery.py +0 -0
  355. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/enrichment_pipeline.py +0 -0
  356. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/feature_meta_builder.py +0 -0
  357. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/llm_prompt.py +0 -0
  358. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/markdown_bootstrap.py +0 -0
  359. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/predicate_prose.py +0 -0
  360. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/prose_backfill.py +0 -0
  361. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/quantile_phrasing.py +0 -0
  362. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/interpretation/sidecars.py +0 -0
  363. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/llm_namer.py +0 -0
  364. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/playbook_loader.py +0 -0
  365. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/playbook_mapper.py +0 -0
  366. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/policy_loader.py +0 -0
  367. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/population_stats.py +0 -0
  368. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/predicate_compiler.py +0 -0
  369. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/rule_extractor.py +0 -0
  370. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/run_context_writer.py +0 -0
  371. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/schemas.py +0 -0
  372. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/seed_yamls/decision_policy.yaml +0 -0
  373. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/seed_yamls/response_schemas.yaml +0 -0
  374. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/seed_yamls/vocabularies.yaml +0 -0
  375. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/shap_runner.py +0 -0
  376. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/snapshot_writer.py +0 -0
  377. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/sql/dashboard_views.sql +0 -0
  378. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/causal/top_drivers_writer.py +0 -0
  379. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/cleaning/__init__.py +0 -0
  380. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/cleaning/base.py +0 -0
  381. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/cleaning/missing_handler.py +0 -0
  382. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/cleaning/outlier_handler.py +0 -0
  383. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/deployment/__init__.py +0 -0
  384. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/deployment/batch_scorer.py +0 -0
  385. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/deployment/champion_challenger.py +0 -0
  386. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/deployment/model_registry.py +0 -0
  387. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/deployment/retraining_trigger.py +0 -0
  388. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/__init__.py +0 -0
  389. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/behavioral_features.py +0 -0
  390. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/customer_segmentation.py +0 -0
  391. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/feature_definitions.py +0 -0
  392. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/feature_engineer.py +0 -0
  393. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/feature_manifest.py +0 -0
  394. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/feature_selector.py +0 -0
  395. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/interaction_features.py +0 -0
  396. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/features/temporal_features.py +0 -0
  397. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/ingestion/__init__.py +0 -0
  398. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/ingestion/load_result.py +0 -0
  399. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/ingestion/loaders.py +0 -0
  400. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/ingestion/source_registry.py +0 -0
  401. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/lifecycle/__init__.py +0 -0
  402. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/lifecycle/config.py +0 -0
  403. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/lifecycle/enrich.py +0 -0
  404. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/lifecycle/validation.py +0 -0
  405. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/__init__.py +0 -0
  406. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/baseline_trainer.py +0 -0
  407. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/cross_validator.py +0 -0
  408. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/data_splitter.py +0 -0
  409. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/feature_profile.py +0 -0
  410. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/feature_scaler.py +0 -0
  411. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/feature_spec.py +0 -0
  412. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/hyperparameter_tuner.py +0 -0
  413. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/imbalance_handler.py +0 -0
  414. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/mlflow_logger.py +0 -0
  415. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/model_comparator.py +0 -0
  416. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/model_evaluator.py +0 -0
  417. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/shap_attribution.py +0 -0
  418. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/spark_baseline_trainer.py +0 -0
  419. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/spark_classifier_wrapper.py +0 -0
  420. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/spark_feature_scaler.py +0 -0
  421. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/threshold_optimizer.py +0 -0
  422. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/modeling/training_preparator.py +0 -0
  423. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/monitoring/__init__.py +0 -0
  424. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/monitoring/alert_manager.py +0 -0
  425. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/monitoring/drift_detector.py +0 -0
  426. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/monitoring/performance_monitor.py +0 -0
  427. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/preprocessing/__init__.py +0 -0
  428. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/preprocessing/transformer_manager.py +0 -0
  429. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/__init__.py +0 -0
  430. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/case_collision.py +0 -0
  431. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/categorical_distribution.py +0 -0
  432. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/categorical_target_analyzer.py +0 -0
  433. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/column_profiler.py +0 -0
  434. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/distribution_analysis.py +0 -0
  435. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/drift_detector.py +0 -0
  436. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/feature_capacity.py +0 -0
  437. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/pattern_analysis_config.py +0 -0
  438. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/profile_result.py +0 -0
  439. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/quality_checks.py +0 -0
  440. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/recommendation_filter.py +0 -0
  441. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/relationship_detector.py +0 -0
  442. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/relationship_recommender.py +0 -0
  443. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/report_generator.py +0 -0
  444. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/scd_analyzer.py +0 -0
  445. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/segment_analyzer.py +0 -0
  446. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/segment_aware_outlier.py +0 -0
  447. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/spark_segment_analyzer.py +0 -0
  448. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/spark_temporal_feature_analyzer.py +0 -0
  449. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/spark_temporal_feature_engineer.py +0 -0
  450. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/spark_time_window_aggregator.py +0 -0
  451. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/stats_helpers.py +0 -0
  452. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/target_level_analyzer.py +0 -0
  453. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/target_validator.py +0 -0
  454. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/temporal_analyzer.py +0 -0
  455. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/temporal_coverage.py +0 -0
  456. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/temporal_feature_analyzer.py +0 -0
  457. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/temporal_feature_engineer.py +0 -0
  458. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/temporal_pattern_analyzer.py +0 -0
  459. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/temporal_quality_checks.py +0 -0
  460. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/temporal_target_analyzer.py +0 -0
  461. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/text_embedder.py +0 -0
  462. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/text_processor.py +0 -0
  463. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/text_reducer.py +0 -0
  464. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/time_series_profiler.py +0 -0
  465. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/time_window_aggregator.py +0 -0
  466. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/type_detector.py +0 -0
  467. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/profiling/window_recommendation.py +0 -0
  468. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scd_history/__init__.py +0 -0
  469. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scd_history/augment.py +0 -0
  470. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scd_history/config.py +0 -0
  471. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scd_history/reconstruct.py +0 -0
  472. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scd_history/validation.py +0 -0
  473. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scoring/__init__.py +0 -0
  474. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scoring/config.py +0 -0
  475. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scoring/data_loader.py +0 -0
  476. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scoring/exceptions.py +0 -0
  477. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/scoring/pipeline_discovery.py +0 -0
  478. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/__init__.py +0 -0
  479. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/access_guard.py +0 -0
  480. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/data_preparer.py +0 -0
  481. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/point_in_time_join.py +0 -0
  482. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/point_in_time_registry.py +0 -0
  483. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/scenario_detector.py +0 -0
  484. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/snapshot_manager.py +0 -0
  485. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/spark_temporal_merger.py +0 -0
  486. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/synthetic_coordinator.py +0 -0
  487. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/temporal_merger.py +0 -0
  488. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/timestamp_discovery.py +0 -0
  489. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/temporal/timestamp_manager.py +0 -0
  490. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/transformation/__init__.py +0 -0
  491. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/transformation/binary_handler.py +0 -0
  492. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/transformation/categorical_encoder.py +0 -0
  493. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/transformation/datetime_transformer.py +0 -0
  494. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/transformation/numeric_transformer.py +0 -0
  495. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/transformation/pipeline.py +0 -0
  496. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/__init__.py +0 -0
  497. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/adversarial_scoring_validator.py +0 -0
  498. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/business_sense_gate.py +0 -0
  499. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/data_quality_gate.py +0 -0
  500. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/data_validators.py +0 -0
  501. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/feature_quality_gate.py +0 -0
  502. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/gates.py +0 -0
  503. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/leakage_gate.py +0 -0
  504. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/model_validity_gate.py +0 -0
  505. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/pipeline_validation_runner.py +0 -0
  506. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/quality_scorer.py +0 -0
  507. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/rule_generator.py +0 -0
  508. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/scoring_pipeline_validator.py +0 -0
  509. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/stages/validation/timeseries_detector.py +0 -0
  510. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/transforms/__init__.py +0 -0
  511. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/transforms/artifact_store.py +0 -0
  512. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/transforms/executor.py +0 -0
  513. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/transforms/fitted.py +0 -0
  514. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/transforms/ops.py +0 -0
  515. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/src/customer_retention/transforms/spark_ops.py +0 -0
  516. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/tests/exploration_notebooks/test_distributed_dtype_safety.py +0 -0
  517. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/tests/exploration_notebooks/test_nb02_case_collision_detection.py +0 -0
  518. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/tests/exploration_notebooks/test_nb06_ratio_registration.py +0 -0
  519. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/tests/exploration_notebooks/test_nb08_categorical_baseline.py +0 -0
  520. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/tests/exploration_notebooks/test_nb08_early_drops.py +0 -0
  521. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/tests/exploration_notebooks/test_nb10_run_pipeline_ordering.py +0 -0
  522. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/tests/scripts/__init__.py +0 -0
  523. {churnkit-1.3.2a2 → churnkit-1.3.2a3}/tests/scripts/test_build_framework_phase_map.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: churnkit
3
- Version: 1.3.2a2
3
+ Version: 1.3.2a3
4
4
  Summary: Structured ML framework for customer churn prediction -- from exploration notebooks to production pipelines, locally or on Databricks.
5
5
  Project-URL: Homepage, https://github.com/aladjov/CR
6
6
  Project-URL: Documentation, https://github.com/aladjov/CR/wiki
@@ -82,7 +82,7 @@ footer,
82
82
  }
83
83
 
84
84
  .block-container {
85
- max-width: 1120px !important;
85
+ max-width: 1320px !important;
86
86
  padding-top: 2rem !important;
87
87
  padding-bottom: 8rem !important;
88
88
  padding-left: 2rem !important;
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "churnkit"
3
- version = "1.03.2a2"
3
+ version = "1.03.2a3"
4
4
  description = "Structured ML framework for customer churn prediction -- from exploration notebooks to production pipelines, locally or on Databricks."
5
5
  readme = "README.md"
6
6
  license = {text = "Apache-2.0"}
@@ -17,7 +17,7 @@ Main module categories:
17
17
  llm_context, iteration)
18
18
  """
19
19
 
20
- __version__ = "1.03.2a2"
20
+ __version__ = "1.03.2a3"
21
21
 
22
22
  # Environment utilities (always available)
23
23
  from .core.compat import (
@@ -101,53 +101,67 @@ def _resolve_scope_filter():
101
101
 
102
102
 
103
103
  def _resolve_already_positive_exclusion():
104
- """Return a Spark-SQL predicate that drops entities whose target label is
105
- already 1 (e.g. ``churned = 0``), resolved from
106
- ``ProjectContext.target_column``. Always-on at scoring time: the trained
107
- model has nothing useful to say about a row that is already a positive
108
- outcome, and surfacing such rows in the CSM-facing dashboard wastes
109
- headcount on accounts the business can no longer recover. Distinct from
110
- ``_resolve_scope_filter`` so the training parity contract stays clean
111
- training cohort keeps positives (the model needs them to learn the
112
- boundary); scoring drops them because they aren't actionable.
113
-
114
- Returns ``None`` when project_context is absent or carries no
115
- ``target_column`` the cell then falls back to the unmodified scope
116
- filter and logs the omission so the operator can see it didn't apply."""
104
+ """Return ``(target_column, landing_fqn, raw_entity_key)`` so scoring can
105
+ drop entities whose target label has EVER been 1 in landing — applied
106
+ by the framework as a ``left_anti`` join against
107
+ ``landing_<target>.filter(<target_col> = 1)``.
108
+
109
+ Entity-level by construction: a row-level ``<target_col> = 0`` clause
110
+ cannot work against a snapshot-panel landing table, because an entity
111
+ with both ``<target_col>=0`` and ``<target_col>=1`` rows would still
112
+ survive the row-level filter (the 0-rows pass; ``distinct(entity_id)``
113
+ re-admits the entity). Anti-join on the "ever positive" entity set is
114
+ the only shape that matches the intent drop the entity wholesale if
115
+ landing has ANY row at the positive outcome.
116
+
117
+ Always-on at scoring time: the trained model has nothing useful to say
118
+ about an already-positive row, and surfacing such rows in the
119
+ CSM-facing dashboard wastes headcount on accounts the business can no
120
+ longer recover. Distinct from ``_resolve_scope_filter`` so the training
121
+ parity contract stays clean — training cohort keeps positives (the
122
+ model needs them to learn the boundary); scoring drops them because
123
+ they aren't actionable.
124
+
125
+ Returns ``(None, None, None)`` when project_context is absent or
126
+ cannot resolve a target column / raw entity key — the cell then falls
127
+ back to the unmodified scope filter and logs the omission so the
128
+ operator can see it didn't apply."""
117
129
  try:
118
130
  from customer_retention.analysis.auto_explorer.project_context import ProjectContext
119
131
  from customer_retention.analysis.auto_explorer.run_namespace import RunNamespace
120
132
  except ImportError:
121
- return None
133
+ return None, None, None
122
134
  _ns = RunNamespace.from_env_or_latest()
123
135
  if _ns is None:
124
- return None
136
+ return None, None, None
125
137
  _path = _ns.project_context_path
126
138
  if not _path.exists():
127
- return None
139
+ return None, None, None
128
140
  _ctx = ProjectContext.load(_path)
129
141
  _target_col = getattr(_ctx, "target_column", None)
130
142
  if not _target_col:
131
- return None
132
- return f"{_target_col} = 0"
133
-
134
-
135
- def _compose_scoring_filter(*parts):
136
- """AND-combine non-empty Spark-SQL predicates, parenthesizing each so
137
- later predicates can't accidentally rebind the earlier ones via
138
- operator-precedence surprises. Returns ``None`` when every part is
139
- falsy."""
140
- _kept = [p for p in parts if p]
141
- if not _kept:
142
- return None
143
- if len(_kept) == 1:
144
- return _kept[0]
145
- return " and ".join(f"({p})" for p in _kept)
143
+ return None, None, None
144
+ _target_name = (
145
+ getattr(_ctx, "target_dataset", None)
146
+ or next(
147
+ (n for n, d in _ctx.datasets.items() if getattr(d, "role", None) == "target"),
148
+ None,
149
+ )
150
+ )
151
+ if _target_name is None and len(_ctx.datasets) == 1:
152
+ _target_name = next(iter(_ctx.datasets))
153
+ if _target_name is None:
154
+ return None, None, None
155
+ _target_ds = _ctx.datasets.get(_target_name)
156
+ _raw_key = getattr(_target_ds, "entity_column", None) if _target_ds is not None else None
157
+ if not _raw_key:
158
+ return None, None, None
159
+ _landing_fqn = f"{CATALOG}.{SCHEMA}.landing_{_target_name}"
160
+ return _target_col, _landing_fqn, _raw_key
146
161
 
147
162
 
148
163
  _scope_filter = _resolve_scope_filter()
149
- _already_positive_exclusion = _resolve_already_positive_exclusion()
150
- _scoring_filter = _compose_scoring_filter(_scope_filter, _already_positive_exclusion)
164
+ _excl_target_col, _excl_landing_fqn, _excl_entity_key = _resolve_already_positive_exclusion()
151
165
 
152
166
  batch_inference_result = None
153
167
  _predictions_status = "UNKNOWN"
@@ -190,12 +204,17 @@ else:
190
204
  print(f"Scope filter (from NB00 project_context): {_scope_filter}")
191
205
  else:
192
206
  print("Scope filter: (none — scoring full entity population)")
193
- if _already_positive_exclusion:
194
- print(f"Already-positive exclusion (target_column): {_already_positive_exclusion}")
207
+ if _excl_target_col and _excl_landing_fqn and _excl_entity_key:
208
+ print(
209
+ f"Already-positive exclusion (entity-level anti-join): "
210
+ f"DROP entity where any row of {_excl_landing_fqn} has "
211
+ f"{_excl_target_col} = 1 (key={_excl_entity_key})"
212
+ )
195
213
  else:
196
214
  print(
197
215
  "Already-positive exclusion: (none — project_context.target_column "
198
- "not set; rows already at the positive outcome will be scored)"
216
+ "or target dataset entity_column not resolvable; entities already "
217
+ "at the positive outcome may be scored)"
199
218
  )
200
219
  config = BatchInferenceConfig(
201
220
  catalog=CATALOG,
@@ -206,7 +225,10 @@ else:
206
225
  risk_tier_high=RISK_TIER_HIGH,
207
226
  risk_tier_medium=RISK_TIER_MEDIUM,
208
227
  inference_timestamp=datetime.now(timezone.utc),
209
- filter_expression=_scoring_filter,
228
+ filter_expression=_scope_filter,
229
+ exclude_already_positive_target_column=_excl_target_col,
230
+ exclude_already_positive_via_table=_excl_landing_fqn,
231
+ exclude_already_positive_entity_key=_excl_entity_key,
210
232
  )
211
233
  batch_inference_result = run_batch_inference(config)
212
234
  _predictions_status = batch_inference_result.summary()
@@ -223,6 +223,31 @@ class BatchInferenceConfig:
223
223
  # ``project_context.datasets[<target>].entity_column`` automatically.
224
224
  filter_via_table_entity_key: Optional[str] = None
225
225
 
226
+ # Entity-level exclusion of rows already at the positive outcome.
227
+ # Distinct from ``filter_expression`` because ``churned = 0`` is a
228
+ # *row-level* predicate and landing is a per-snapshot panel: an entity
229
+ # that was churned=0 in earlier snapshots and churned=1 later still has
230
+ # rows passing the row-level filter, so its entity_id survives
231
+ # ``.select().distinct()`` and the scoring cohort silently leaks
232
+ # already-positive accounts onto the CSM-facing dashboard.
233
+ #
234
+ # Set all three together to drop any entity whose target has EVER been
235
+ # 1 across any row of ``via_table`` (the landing table for the target
236
+ # dataset). Applied as a one-sided ``left_anti`` join after the scope
237
+ # filter resolves entity_df — single Spark job, narrow shuffle, no
238
+ # collect-to-driver. The trained model has nothing useful to say about
239
+ # an already-positive row and the business can no longer recover that
240
+ # account; no opt-out by design.
241
+ #
242
+ # When any of the three fields is ``None`` the exclusion is silently
243
+ # skipped. The c04 stage generator populates them automatically from
244
+ # ``project_context.target_column`` + the target dataset's
245
+ # ``entity_column`` so old callers (that pre-date this change) keep
246
+ # working unchanged but get the looser row-level semantics.
247
+ exclude_already_positive_target_column: Optional[str] = None
248
+ exclude_already_positive_via_table: Optional[str] = None
249
+ exclude_already_positive_entity_key: Optional[str] = None
250
+
226
251
 
227
252
  @dataclass
228
253
  class BatchInferenceResult:
@@ -480,14 +505,13 @@ def _run_databricks(config: BatchInferenceConfig) -> BatchInferenceResult:
480
505
  t_prep = time.perf_counter()
481
506
  df_customers = spark.table(customer_table)
482
507
  if config.filter_expression:
483
- # NB00's `sample_filter` predicate is stored in pandas/Python
484
- # syntax (`column in ['a', 'b']`) because exploration filters via
485
- # `df.query()`. Spark `df.filter()` needs SQL-tuple syntax
486
- # (`column IN ('a', 'b')`). The same translator landing applies
487
- # before its `df.filter(...)` call (see `findings_parser`
488
- # invocation of `_spark_safe_query_expr`) — apply it here so the
489
- # same predicate string drives both stages without operator
490
- # intervention.
508
+ # The NB00 sample_filter predicate is stored in pandas-style
509
+ # syntax (Python list literals after IN) because exploration
510
+ # filters via the pandas query API. Spark df.filter needs
511
+ # SQL-tuple syntax instead. The same translator landing applies
512
+ # before its df.filter call (see findings_parser invocation of
513
+ # _spark_safe_query_expr) — apply it here so the same predicate
514
+ # string drives both stages without operator intervention.
491
515
  from customer_retention.core.compat import _spark_safe_query_expr
492
516
  _sql_filter = _spark_safe_query_expr(config.filter_expression)
493
517
  # Register sibling-temp-views for any bare-name table references
@@ -576,6 +600,42 @@ def _run_databricks(config: BatchInferenceConfig) -> BatchInferenceResult:
576
600
  entity_count = int(entity_df.count())
577
601
  prep_seconds = time.perf_counter() - t_prep
578
602
  _emit(f"{entity_count:,} entities after filter/dedup (prep {prep_seconds:.1f}s)")
603
+
604
+ # Entity-level already-positive exclusion. Runs in addition to the
605
+ # row-level scope filter above because ``churned = 0`` applied per-row
606
+ # to a snapshot-panel landing table can never produce the right
607
+ # answer: an entity with both churned=0 and churned=1 rows passes the
608
+ # row-level filter and slips into the scored cohort. Here we build
609
+ # the "ever-positive" entity set from landing and ``left_anti`` join
610
+ # it out — one narrow shuffle, no collect-to-driver, no temp views.
611
+ _excl_col = config.exclude_already_positive_target_column
612
+ _excl_table = config.exclude_already_positive_via_table
613
+ _excl_key = config.exclude_already_positive_entity_key
614
+ if _excl_col and _excl_table and _excl_key:
615
+ from pyspark.sql.functions import col as _col # noqa: N812 — Spark API name
616
+
617
+ if not spark.catalog.tableExists(_excl_table):
618
+ _emit(
619
+ f"WARNING: exclude_already_positive_via_table {_excl_table} does not "
620
+ "exist; skipping entity-level already-positive exclusion."
621
+ )
622
+ else:
623
+ _ever_positive = (
624
+ spark.table(_excl_table)
625
+ .filter(_col(_excl_col) == lit(1))
626
+ .select(_col(_excl_key).alias("entity_id"))
627
+ .distinct()
628
+ )
629
+ entity_df = entity_df.join(_ever_positive, on="entity_id", how="left_anti")
630
+ _post_excl = int(entity_df.count())
631
+ _dropped = entity_count - _post_excl
632
+ _emit(
633
+ f"dropped {_dropped:,} entities with {_excl_col}=1 in any "
634
+ f"{_excl_table} row (entity-level exclusion); "
635
+ f"{_post_excl:,} entities remain"
636
+ )
637
+ entity_count = _post_excl
638
+
579
639
  if entity_count == 0:
580
640
  raise ValueError(
581
641
  f"Scope filter + distinct produced 0 entities in {customer_table}; "
File without changes
File without changes
File without changes
File without changes