bloomery 0.1.0__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 (506) hide show
  1. bloomery-0.1.0/.gitignore +245 -0
  2. bloomery-0.1.0/CHANGELOG.md +154 -0
  3. bloomery-0.1.0/LICENSE +21 -0
  4. bloomery-0.1.0/PKG-INFO +224 -0
  5. bloomery-0.1.0/README.md +174 -0
  6. bloomery-0.1.0/examples/README.md +33 -0
  7. bloomery-0.1.0/pyproject.toml +547 -0
  8. bloomery-0.1.0/src/bloomery/__init__.py +164 -0
  9. bloomery-0.1.0/src/bloomery/_version.py +24 -0
  10. bloomery-0.1.0/src/bloomery/cli/__init__.py +482 -0
  11. bloomery-0.1.0/src/bloomery/cli/io.py +167 -0
  12. bloomery-0.1.0/src/bloomery/cli/render.py +167 -0
  13. bloomery-0.1.0/src/bloomery/cli/serialize.py +111 -0
  14. bloomery-0.1.0/src/bloomery/compile.py +64 -0
  15. bloomery-0.1.0/src/bloomery/dialects/__init__.py +81 -0
  16. bloomery-0.1.0/src/bloomery/dialects/base.py +160 -0
  17. bloomery-0.1.0/src/bloomery/dialects/duckdb.py +70 -0
  18. bloomery-0.1.0/src/bloomery/dialects/postgres.py +211 -0
  19. bloomery-0.1.0/src/bloomery/dialects/trino.py +80 -0
  20. bloomery-0.1.0/src/bloomery/emit/__init__.py +68 -0
  21. bloomery-0.1.0/src/bloomery/emit/base.py +125 -0
  22. bloomery-0.1.0/src/bloomery/emit/cube/__init__.py +281 -0
  23. bloomery-0.1.0/src/bloomery/emit/dbt/__init__.py +731 -0
  24. bloomery-0.1.0/src/bloomery/emit/lower/__init__.py +97 -0
  25. bloomery-0.1.0/src/bloomery/emit/lower/marts.py +170 -0
  26. bloomery-0.1.0/src/bloomery/emit/lower/predicates.py +78 -0
  27. bloomery-0.1.0/src/bloomery/emit/lower/quality_mart.py +373 -0
  28. bloomery-0.1.0/src/bloomery/emit/lower/reconcile.py +435 -0
  29. bloomery-0.1.0/src/bloomery/emit/lower/silver.py +1416 -0
  30. bloomery-0.1.0/src/bloomery/emit/metricflow/__init__.py +576 -0
  31. bloomery-0.1.0/src/bloomery/emit/sqlmesh/__init__.py +798 -0
  32. bloomery-0.1.0/src/bloomery/emit/steps.py +753 -0
  33. bloomery-0.1.0/src/bloomery/errors.py +673 -0
  34. bloomery-0.1.0/src/bloomery/evidence.py +336 -0
  35. bloomery-0.1.0/src/bloomery/guardrails/__init__.py +12 -0
  36. bloomery-0.1.0/src/bloomery/guardrails/additivity.py +113 -0
  37. bloomery-0.1.0/src/bloomery/guardrails/arithmetic.py +195 -0
  38. bloomery-0.1.0/src/bloomery/guardrails/asserts.py +177 -0
  39. bloomery-0.1.0/src/bloomery/guardrails/conflict.py +75 -0
  40. bloomery-0.1.0/src/bloomery/guardrails/grain.py +173 -0
  41. bloomery-0.1.0/src/bloomery/guardrails/operands.py +115 -0
  42. bloomery-0.1.0/src/bloomery/guardrails/quality.py +1073 -0
  43. bloomery-0.1.0/src/bloomery/guardrails/stage.py +91 -0
  44. bloomery-0.1.0/src/bloomery/ir/__init__.py +111 -0
  45. bloomery-0.1.0/src/bloomery/ir/fingerprint.py +80 -0
  46. bloomery-0.1.0/src/bloomery/ir/lower.py +88 -0
  47. bloomery-0.1.0/src/bloomery/ir/nodes.py +820 -0
  48. bloomery-0.1.0/src/bloomery/marts/__init__.py +18 -0
  49. bloomery-0.1.0/src/bloomery/marts/flatten.py +634 -0
  50. bloomery-0.1.0/src/bloomery/naming.py +55 -0
  51. bloomery-0.1.0/src/bloomery/plan/__init__.py +19 -0
  52. bloomery-0.1.0/src/bloomery/plan/diff.py +1484 -0
  53. bloomery-0.1.0/src/bloomery/plan/model.py +131 -0
  54. bloomery-0.1.0/src/bloomery/planner/__init__.py +70 -0
  55. bloomery-0.1.0/src/bloomery/planner/coverage.py +259 -0
  56. bloomery-0.1.0/src/bloomery/planner/explain.py +143 -0
  57. bloomery-0.1.0/src/bloomery/planner/filters.py +302 -0
  58. bloomery-0.1.0/src/bloomery/planner/metricflow_planner.py +200 -0
  59. bloomery-0.1.0/src/bloomery/planner/names.py +218 -0
  60. bloomery-0.1.0/src/bloomery/planner/parse.py +566 -0
  61. bloomery-0.1.0/src/bloomery/planner/policy.py +55 -0
  62. bloomery-0.1.0/src/bloomery/planner/request.py +325 -0
  63. bloomery-0.1.0/src/bloomery/planner/result.py +114 -0
  64. bloomery-0.1.0/src/bloomery/py.typed +0 -0
  65. bloomery-0.1.0/src/bloomery/quality/__init__.py +219 -0
  66. bloomery-0.1.0/src/bloomery/quality/catalogue.py +122 -0
  67. bloomery-0.1.0/src/bloomery/quality/charset.py +107 -0
  68. bloomery-0.1.0/src/bloomery/quality/dedupe.py +87 -0
  69. bloomery-0.1.0/src/bloomery/quality/flags.py +163 -0
  70. bloomery-0.1.0/src/bloomery/quality/lower.py +569 -0
  71. bloomery-0.1.0/src/bloomery/quality/mart.py +343 -0
  72. bloomery-0.1.0/src/bloomery/quality/pattern.py +107 -0
  73. bloomery-0.1.0/src/bloomery/quality/predicates.py +648 -0
  74. bloomery-0.1.0/src/bloomery/quality/reconcile.py +117 -0
  75. bloomery-0.1.0/src/bloomery/quality/reject.py +105 -0
  76. bloomery-0.1.0/src/bloomery/resolve/__init__.py +24 -0
  77. bloomery-0.1.0/src/bloomery/resolve/build.py +1005 -0
  78. bloomery-0.1.0/src/bloomery/resolve/graph.py +263 -0
  79. bloomery-0.1.0/src/bloomery/resolve/metrics.py +94 -0
  80. bloomery-0.1.0/src/bloomery/resolve/order.py +77 -0
  81. bloomery-0.1.0/src/bloomery/resolve/reach.py +98 -0
  82. bloomery-0.1.0/src/bloomery/resolve/recipes.py +117 -0
  83. bloomery-0.1.0/src/bloomery/resolve/refs.py +265 -0
  84. bloomery-0.1.0/src/bloomery/resolve/resolution.py +116 -0
  85. bloomery-0.1.0/src/bloomery/resolve/steps.py +785 -0
  86. bloomery-0.1.0/src/bloomery/runtime/__init__.py +26 -0
  87. bloomery-0.1.0/src/bloomery/runtime/hydration.py +178 -0
  88. bloomery-0.1.0/src/bloomery/runtime/sql_client.py +97 -0
  89. bloomery-0.1.0/src/bloomery/schema.py +287 -0
  90. bloomery-0.1.0/src/bloomery/spec/__init__.py +107 -0
  91. bloomery-0.1.0/src/bloomery/spec/catalog.py +119 -0
  92. bloomery-0.1.0/src/bloomery/spec/common.py +289 -0
  93. bloomery-0.1.0/src/bloomery/spec/entity.py +128 -0
  94. bloomery-0.1.0/src/bloomery/spec/mapping.py +204 -0
  95. bloomery-0.1.0/src/bloomery/spec/marts.py +158 -0
  96. bloomery-0.1.0/src/bloomery/spec/metrics.py +81 -0
  97. bloomery-0.1.0/src/bloomery/spec/project.py +182 -0
  98. bloomery-0.1.0/src/bloomery/spec/quality.py +920 -0
  99. bloomery-0.1.0/src/bloomery/spec/steps.py +187 -0
  100. bloomery-0.1.0/src/bloomery/steps/__init__.py +109 -0
  101. bloomery-0.1.0/src/bloomery/steps/contract.py +212 -0
  102. bloomery-0.1.0/src/bloomery/steps/manifest.py +399 -0
  103. bloomery-0.1.0/src/bloomery/steps/registry.py +174 -0
  104. bloomery-0.1.0/src/bloomery/steps/splice.py +160 -0
  105. bloomery-0.1.0/src/bloomery/transforms/__init__.py +37 -0
  106. bloomery-0.1.0/src/bloomery/transforms/_builtins.py +405 -0
  107. bloomery-0.1.0/src/bloomery/transforms/registry.py +177 -0
  108. bloomery-0.1.0/src/bloomery/typing/__init__.py +37 -0
  109. bloomery-0.1.0/src/bloomery/typing/check.py +182 -0
  110. bloomery-0.1.0/src/bloomery/typing/types.py +184 -0
  111. bloomery-0.1.0/tests/README.md +60 -0
  112. bloomery-0.1.0/tests/__init__.py +0 -0
  113. bloomery-0.1.0/tests/bench/__init__.py +0 -0
  114. bloomery-0.1.0/tests/bench/test_hydration.py +220 -0
  115. bloomery-0.1.0/tests/chaos/__init__.py +0 -0
  116. bloomery-0.1.0/tests/chaos/test_mutation_harness.py +113 -0
  117. bloomery-0.1.0/tests/conftest.py +189 -0
  118. bloomery-0.1.0/tests/e2e/__init__.py +0 -0
  119. bloomery-0.1.0/tests/e2e/test_cube_meta.py +116 -0
  120. bloomery-0.1.0/tests/e2e/test_dbt_parse.py +298 -0
  121. bloomery-0.1.0/tests/e2e/test_sqlmesh_replan.py +520 -0
  122. bloomery-0.1.0/tests/engines/__init__.py +0 -0
  123. bloomery-0.1.0/tests/engines/test_postgres_execution.py +134 -0
  124. bloomery-0.1.0/tests/engines/test_postgres_quality.py +160 -0
  125. bloomery-0.1.0/tests/engines/test_postgres_reconcile.py +121 -0
  126. bloomery-0.1.0/tests/engines/test_postgres_text_rules.py +132 -0
  127. bloomery-0.1.0/tests/engines/test_trino.py +341 -0
  128. bloomery-0.1.0/tests/equivalence/README.md +33 -0
  129. bloomery-0.1.0/tests/equivalence/__init__.py +0 -0
  130. bloomery-0.1.0/tests/equivalence/golden_requests.yaml +56 -0
  131. bloomery-0.1.0/tests/equivalence/known_divergences.yaml +9 -0
  132. bloomery-0.1.0/tests/equivalence/reference_sql/aov_by_month.sql +6 -0
  133. bloomery-0.1.0/tests/equivalence/reference_sql/aov_by_store.sql +3 -0
  134. bloomery-0.1.0/tests/equivalence/reference_sql/revenue_by_month.sql +5 -0
  135. bloomery-0.1.0/tests/equivalence/reference_sql/revenue_ungrouped.sql +2 -0
  136. bloomery-0.1.0/tests/equivalence/test_three_way.py +203 -0
  137. bloomery-0.1.0/tests/execution/__init__.py +0 -0
  138. bloomery-0.1.0/tests/execution/test_dedupe_and_audits.py +317 -0
  139. bloomery-0.1.0/tests/execution/test_dirty_corpus.py +587 -0
  140. bloomery-0.1.0/tests/execution/test_fanout_trap.py +98 -0
  141. bloomery-0.1.0/tests/execution/test_identity_resolution.py +211 -0
  142. bloomery-0.1.0/tests/execution/test_marts.py +136 -0
  143. bloomery-0.1.0/tests/execution/test_merge_gates.py +138 -0
  144. bloomery-0.1.0/tests/execution/test_path_conflict.py +59 -0
  145. bloomery-0.1.0/tests/execution/test_pattern_anchoring.py +107 -0
  146. bloomery-0.1.0/tests/execution/test_planner_filters.py +206 -0
  147. bloomery-0.1.0/tests/execution/test_planner_numbers.py +290 -0
  148. bloomery-0.1.0/tests/execution/test_quality_mart.py +261 -0
  149. bloomery-0.1.0/tests/execution/test_quality_precedence.py +602 -0
  150. bloomery-0.1.0/tests/execution/test_quarantine_replay.py +425 -0
  151. bloomery-0.1.0/tests/execution/test_reconcile_null_keys.py +134 -0
  152. bloomery-0.1.0/tests/execution/test_sqlmesh_duckdb.py +87 -0
  153. bloomery-0.1.0/tests/execution/test_step_consistency.py +107 -0
  154. bloomery-0.1.0/tests/fixtures/.gitkeep +0 -0
  155. bloomery-0.1.0/tests/fixtures/coverage_check/entity_model.yaml +36 -0
  156. bloomery-0.1.0/tests/fixtures/coverage_check/mapping_customers.yaml +7 -0
  157. bloomery-0.1.0/tests/fixtures/coverage_check/mapping_orders.yaml +8 -0
  158. bloomery-0.1.0/tests/fixtures/currency_convert_refusal/entity_model.yaml +15 -0
  159. bloomery-0.1.0/tests/fixtures/currency_convert_refusal/mapping.yaml +9 -0
  160. bloomery-0.1.0/tests/fixtures/dirty/README.md +143 -0
  161. bloomery-0.1.0/tests/fixtures/dirty/dates.csv +22 -0
  162. bloomery-0.1.0/tests/fixtures/dirty/enums.csv +19 -0
  163. bloomery-0.1.0/tests/fixtures/dirty/extremes.csv +21 -0
  164. bloomery-0.1.0/tests/fixtures/dirty/keys.csv +23 -0
  165. bloomery-0.1.0/tests/fixtures/dirty/numerics.csv +21 -0
  166. bloomery-0.1.0/tests/fixtures/dirty/refs.csv +17 -0
  167. bloomery-0.1.0/tests/fixtures/dirty/unicode.csv +23 -0
  168. bloomery-0.1.0/tests/fixtures/dirty_corpus/catalog.yaml +13 -0
  169. bloomery-0.1.0/tests/fixtures/dirty_corpus/entity_model.yaml +244 -0
  170. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_customers.yaml +10 -0
  171. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_dates.yaml +20 -0
  172. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_enums.yaml +23 -0
  173. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_extremes_decimal.yaml +21 -0
  174. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_extremes_integer.yaml +16 -0
  175. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_extremes_text.yaml +21 -0
  176. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_extremes_timestamp.yaml +14 -0
  177. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_keys.yaml +18 -0
  178. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_numerics.yaml +23 -0
  179. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_ref_parents.yaml +21 -0
  180. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_refs.yaml +20 -0
  181. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_refs_routed.yaml +38 -0
  182. bloomery-0.1.0/tests/fixtures/dirty_corpus/mapping_unicode.yaml +65 -0
  183. bloomery-0.1.0/tests/fixtures/ecom_basic/catalog.yaml +54 -0
  184. bloomery-0.1.0/tests/fixtures/ecom_basic/entity_model.yaml +26 -0
  185. bloomery-0.1.0/tests/fixtures/ecom_basic/mapping_order_items.yaml +15 -0
  186. bloomery-0.1.0/tests/fixtures/ecom_basic/mapping_orders.yaml +7 -0
  187. bloomery-0.1.0/tests/fixtures/ecom_basic/marts.yaml +13 -0
  188. bloomery-0.1.0/tests/fixtures/ecom_basic/metrics.yaml +21 -0
  189. bloomery-0.1.0/tests/fixtures/evolution_v1/catalog.yaml +27 -0
  190. bloomery-0.1.0/tests/fixtures/evolution_v1/entity_model.yaml +13 -0
  191. bloomery-0.1.0/tests/fixtures/evolution_v1/mapping.yaml +11 -0
  192. bloomery-0.1.0/tests/fixtures/evolution_v1/metrics.yaml +8 -0
  193. bloomery-0.1.0/tests/fixtures/evolution_v2/catalog.yaml +27 -0
  194. bloomery-0.1.0/tests/fixtures/evolution_v2/entity_model.yaml +14 -0
  195. bloomery-0.1.0/tests/fixtures/evolution_v2/mapping.yaml +14 -0
  196. bloomery-0.1.0/tests/fixtures/evolution_v2/metrics.yaml +8 -0
  197. bloomery-0.1.0/tests/fixtures/evolution_v3/catalog.yaml +27 -0
  198. bloomery-0.1.0/tests/fixtures/evolution_v3/entity_model.yaml +16 -0
  199. bloomery-0.1.0/tests/fixtures/evolution_v3/mapping.yaml +14 -0
  200. bloomery-0.1.0/tests/fixtures/evolution_v3/metrics.yaml +14 -0
  201. bloomery-0.1.0/tests/fixtures/evolution_v4/catalog.yaml +27 -0
  202. bloomery-0.1.0/tests/fixtures/evolution_v4/entity_model.yaml +15 -0
  203. bloomery-0.1.0/tests/fixtures/evolution_v4/mapping.yaml +16 -0
  204. bloomery-0.1.0/tests/fixtures/evolution_v4/metrics.yaml +14 -0
  205. bloomery-0.1.0/tests/fixtures/evolution_v5/catalog.yaml +27 -0
  206. bloomery-0.1.0/tests/fixtures/evolution_v5/entity_model.yaml +17 -0
  207. bloomery-0.1.0/tests/fixtures/evolution_v5/mapping.yaml +14 -0
  208. bloomery-0.1.0/tests/fixtures/evolution_v5/metrics.yaml +8 -0
  209. bloomery-0.1.0/tests/fixtures/fanout_trap/catalog.yaml +30 -0
  210. bloomery-0.1.0/tests/fixtures/fanout_trap/entity_model.yaml +26 -0
  211. bloomery-0.1.0/tests/fixtures/fanout_trap/mapping_order_items.yaml +18 -0
  212. bloomery-0.1.0/tests/fixtures/fanout_trap/mapping_orders.yaml +9 -0
  213. bloomery-0.1.0/tests/fixtures/fanout_trap/marts.yaml +14 -0
  214. bloomery-0.1.0/tests/fixtures/fanout_trap/metrics.yaml +19 -0
  215. bloomery-0.1.0/tests/fixtures/identity_resolution/catalog.yaml +28 -0
  216. bloomery-0.1.0/tests/fixtures/identity_resolution/entity_model.yaml +33 -0
  217. bloomery-0.1.0/tests/fixtures/identity_resolution/mapping_billing.yaml +11 -0
  218. bloomery-0.1.0/tests/fixtures/identity_resolution/mapping_crm.yaml +9 -0
  219. bloomery-0.1.0/tests/fixtures/identity_resolution/marts.yaml +11 -0
  220. bloomery-0.1.0/tests/fixtures/identity_resolution/metrics.yaml +6 -0
  221. bloomery-0.1.0/tests/fixtures/identity_resolution/steps.yaml +27 -0
  222. bloomery-0.1.0/tests/fixtures/minimal/entity_model.yaml +10 -0
  223. bloomery-0.1.0/tests/fixtures/minimal/mapping.yaml +8 -0
  224. bloomery-0.1.0/tests/fixtures/multi_mart_refusal/catalog.yaml +10 -0
  225. bloomery-0.1.0/tests/fixtures/multi_mart_refusal/entity_model.yaml +21 -0
  226. bloomery-0.1.0/tests/fixtures/multi_mart_refusal/mapping_order_items.yaml +9 -0
  227. bloomery-0.1.0/tests/fixtures/multi_mart_refusal/mapping_orders.yaml +8 -0
  228. bloomery-0.1.0/tests/fixtures/multi_mart_refusal/marts.yaml +18 -0
  229. bloomery-0.1.0/tests/fixtures/multi_mart_refusal/metrics.yaml +12 -0
  230. bloomery-0.1.0/tests/fixtures/non_additive_aov/catalog.yaml +12 -0
  231. bloomery-0.1.0/tests/fixtures/non_additive_aov/entity_model.yaml +14 -0
  232. bloomery-0.1.0/tests/fixtures/non_additive_aov/mapping.yaml +9 -0
  233. bloomery-0.1.0/tests/fixtures/non_additive_aov/marts.yaml +12 -0
  234. bloomery-0.1.0/tests/fixtures/non_additive_aov/metrics.yaml +19 -0
  235. bloomery-0.1.0/tests/fixtures/path_conflict/catalog.yaml +18 -0
  236. bloomery-0.1.0/tests/fixtures/path_conflict/entity_model.yaml +13 -0
  237. bloomery-0.1.0/tests/fixtures/path_conflict/mapping.yaml +14 -0
  238. bloomery-0.1.0/tests/fixtures/quality_precedence/catalog.yaml +20 -0
  239. bloomery-0.1.0/tests/fixtures/quality_precedence/entity_model.yaml +82 -0
  240. bloomery-0.1.0/tests/fixtures/quality_precedence/mapping_codes.yaml +22 -0
  241. bloomery-0.1.0/tests/fixtures/quality_precedence/mapping_dups.yaml +24 -0
  242. bloomery-0.1.0/tests/fixtures/quality_precedence/mapping_lines.yaml +31 -0
  243. bloomery-0.1.0/tests/fixtures/quality_precedence/marts.yaml +37 -0
  244. bloomery-0.1.0/tests/fixtures/quality_precedence/metrics.yaml +12 -0
  245. bloomery-0.1.0/tests/fixtures/role_playing_dates/catalog.yaml +11 -0
  246. bloomery-0.1.0/tests/fixtures/role_playing_dates/entity_model.yaml +13 -0
  247. bloomery-0.1.0/tests/fixtures/role_playing_dates/mapping.yaml +9 -0
  248. bloomery-0.1.0/tests/fixtures/role_playing_dates/marts.yaml +12 -0
  249. bloomery-0.1.0/tests/fixtures/role_playing_dates/metrics.yaml +7 -0
  250. bloomery-0.1.0/tests/fixtures/scd2_customers/entity_model.yaml +14 -0
  251. bloomery-0.1.0/tests/fixtures/scd2_customers/mapping.yaml +8 -0
  252. bloomery-0.1.0/tests/fixtures/scd2_mart_refusal/catalog.yaml +10 -0
  253. bloomery-0.1.0/tests/fixtures/scd2_mart_refusal/entity_model.yaml +35 -0
  254. bloomery-0.1.0/tests/fixtures/scd2_mart_refusal/mapping_customers.yaml +8 -0
  255. bloomery-0.1.0/tests/fixtures/scd2_mart_refusal/mapping_orders.yaml +9 -0
  256. bloomery-0.1.0/tests/fixtures/scd2_mart_refusal/marts.yaml +25 -0
  257. bloomery-0.1.0/tests/fixtures/scd2_mart_refusal/metrics.yaml +12 -0
  258. bloomery-0.1.0/tests/fixtures/semi_additive_inventory/catalog.yaml +18 -0
  259. bloomery-0.1.0/tests/fixtures/semi_additive_inventory/entity_model.yaml +37 -0
  260. bloomery-0.1.0/tests/fixtures/semi_additive_inventory/mapping.yaml +16 -0
  261. bloomery-0.1.0/tests/fixtures/semi_additive_inventory/marts.yaml +12 -0
  262. bloomery-0.1.0/tests/fixtures/semi_additive_inventory/metrics.yaml +12 -0
  263. bloomery-0.1.0/tests/fixtures/step_resolution/entity_model.yaml +19 -0
  264. bloomery-0.1.0/tests/fixtures/step_resolution/mapping.yaml +9 -0
  265. bloomery-0.1.0/tests/fixtures/step_resolution/steps.yaml +11 -0
  266. bloomery-0.1.0/tests/golden/.gitkeep +0 -0
  267. bloomery-0.1.0/tests/golden/ecom_basic/cube/model/cubes/order_items.yml +59 -0
  268. bloomery-0.1.0/tests/golden/ecom_basic/cube/model/views/order_items_view.yml +7 -0
  269. bloomery-0.1.0/tests/golden/ecom_basic/dbt/postgres/dbt_project.yml +17 -0
  270. bloomery-0.1.0/tests/golden/ecom_basic/dbt/postgres/macros/generate_schema_name.sql +9 -0
  271. bloomery-0.1.0/tests/golden/ecom_basic/dbt/postgres/models/gold/dim_date.sql +11 -0
  272. bloomery-0.1.0/tests/golden/ecom_basic/dbt/postgres/models/gold/mart_order_items.sql +20 -0
  273. bloomery-0.1.0/tests/golden/ecom_basic/dbt/postgres/models/schema.yml +9 -0
  274. bloomery-0.1.0/tests/golden/ecom_basic/dbt/postgres/models/silver/order.sql +10 -0
  275. bloomery-0.1.0/tests/golden/ecom_basic/dbt/postgres/models/silver/order_item.sql +13 -0
  276. bloomery-0.1.0/tests/golden/ecom_basic/dbt/postgres/models/sources.yml +9 -0
  277. bloomery-0.1.0/tests/golden/ecom_basic/metricflow/manifest.json +201 -0
  278. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/duckdb/models/gold/dim_date.sql +15 -0
  279. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/duckdb/models/gold/mart_order_items.sql +25 -0
  280. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/duckdb/models/silver/order.sql +14 -0
  281. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/duckdb/models/silver/order_item.sql +19 -0
  282. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/postgres/models/gold/dim_date.sql +15 -0
  283. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/postgres/models/gold/mart_order_items.sql +25 -0
  284. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/postgres/models/silver/order.sql +14 -0
  285. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/postgres/models/silver/order_item.sql +19 -0
  286. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/trino/models/gold/dim_date.sql +15 -0
  287. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/trino/models/gold/mart_order_items.sql +25 -0
  288. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/trino/models/silver/order.sql +14 -0
  289. bloomery-0.1.0/tests/golden/ecom_basic/sqlmesh/trino/models/silver/order_item.sql +19 -0
  290. bloomery-0.1.0/tests/golden/identity_resolution/cube/model/cubes/customers.yml +46 -0
  291. bloomery-0.1.0/tests/golden/identity_resolution/cube/model/views/customers_view.yml +7 -0
  292. bloomery-0.1.0/tests/golden/identity_resolution/sqlmesh/duckdb/audits/step_customer_confidence_is_high.sql +13 -0
  293. bloomery-0.1.0/tests/golden/identity_resolution/sqlmesh/duckdb/audits/step_customer_xref_canonical_id_references_customer.sql +18 -0
  294. bloomery-0.1.0/tests/golden/identity_resolution/sqlmesh/duckdb/models/gold/dim_date.sql +15 -0
  295. bloomery-0.1.0/tests/golden/identity_resolution/sqlmesh/duckdb/models/gold/mart_customers.sql +18 -0
  296. bloomery-0.1.0/tests/golden/identity_resolution/sqlmesh/duckdb/models/silver/customer.py +63 -0
  297. bloomery-0.1.0/tests/golden/identity_resolution/sqlmesh/duckdb/models/silver/customer_billing.sql +16 -0
  298. bloomery-0.1.0/tests/golden/identity_resolution/sqlmesh/duckdb/models/silver/customer_crm.sql +16 -0
  299. bloomery-0.1.0/tests/golden/identity_resolution/sqlmesh/duckdb/models/silver/customer_xref.py +63 -0
  300. bloomery-0.1.0/tests/golden/minimal/sqlmesh/duckdb/models/silver/event.sql +15 -0
  301. bloomery-0.1.0/tests/golden/minimal/sqlmesh/postgres/models/silver/event.sql +15 -0
  302. bloomery-0.1.0/tests/golden/minimal/sqlmesh/trino/models/silver/event.sql +15 -0
  303. bloomery-0.1.0/tests/golden/multi_mart_refusal/metricflow/manifest.json +305 -0
  304. bloomery-0.1.0/tests/golden/non_additive_aov/cube/model/cubes/orders.yml +60 -0
  305. bloomery-0.1.0/tests/golden/non_additive_aov/cube/model/views/orders_view.yml +7 -0
  306. bloomery-0.1.0/tests/golden/non_additive_aov/metricflow/manifest.json +291 -0
  307. bloomery-0.1.0/tests/golden/path_conflict/sqlmesh/duckdb/audits/item_net_price_reconcile.sql +7 -0
  308. bloomery-0.1.0/tests/golden/path_conflict/sqlmesh/duckdb/models/silver/item.sql +17 -0
  309. bloomery-0.1.0/tests/golden/role_playing_dates/cube/model/cubes/orders.yml +75 -0
  310. bloomery-0.1.0/tests/golden/role_playing_dates/cube/model/views/orders_view.yml +7 -0
  311. bloomery-0.1.0/tests/golden/role_playing_dates/metricflow/manifest.json +193 -0
  312. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/duckdb/models/gold/dim_date.sql +15 -0
  313. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/duckdb/models/gold/mart_orders.sql +24 -0
  314. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/duckdb/models/silver/order.sql +16 -0
  315. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/postgres/models/gold/dim_date.sql +15 -0
  316. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/postgres/models/gold/mart_orders.sql +24 -0
  317. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/postgres/models/silver/order.sql +16 -0
  318. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/trino/models/gold/dim_date.sql +15 -0
  319. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/trino/models/gold/mart_orders.sql +24 -0
  320. bloomery-0.1.0/tests/golden/role_playing_dates/sqlmesh/trino/models/silver/order.sql +16 -0
  321. bloomery-0.1.0/tests/golden/scd2_customers/dbt/postgres/dbt_project.yml +11 -0
  322. bloomery-0.1.0/tests/golden/scd2_customers/dbt/postgres/macros/generate_schema_name.sql +9 -0
  323. bloomery-0.1.0/tests/golden/scd2_customers/dbt/postgres/models/schema.yml +16 -0
  324. bloomery-0.1.0/tests/golden/scd2_customers/dbt/postgres/models/sources.yml +8 -0
  325. bloomery-0.1.0/tests/golden/scd2_customers/dbt/postgres/snapshots/customer_snapshot.sql +14 -0
  326. bloomery-0.1.0/tests/golden/scd2_customers/sqlmesh/duckdb/models/silver/customer.sql +16 -0
  327. bloomery-0.1.0/tests/golden/schema/catalog.json +403 -0
  328. bloomery-0.1.0/tests/golden/schema/entity_model.json +632 -0
  329. bloomery-0.1.0/tests/golden/schema/mapping.json +1158 -0
  330. bloomery-0.1.0/tests/golden/schema/marts.json +248 -0
  331. bloomery-0.1.0/tests/golden/schema/metrics.json +241 -0
  332. bloomery-0.1.0/tests/golden/schema/steps.json +222 -0
  333. bloomery-0.1.0/tests/golden/semi_additive_inventory/cube/model/cubes/data_quality.yml +92 -0
  334. bloomery-0.1.0/tests/golden/semi_additive_inventory/cube/model/cubes/inventory.yml +53 -0
  335. bloomery-0.1.0/tests/golden/semi_additive_inventory/cube/model/views/data_quality_view.yml +7 -0
  336. bloomery-0.1.0/tests/golden/semi_additive_inventory/cube/model/views/inventory_view.yml +7 -0
  337. bloomery-0.1.0/tests/golden/semi_additive_inventory/metricflow/manifest.json +609 -0
  338. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/audits/inventory_level_conservation.sql +83 -0
  339. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/audits/inventory_level_ingestion_metadata.sql +17 -0
  340. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/audits/inventory_level_stock_level_not_null.sql +44 -0
  341. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/audits/stock_level_matches_snapshot_reconcile.sql +8 -0
  342. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/models/gold/dim_date.sql +15 -0
  343. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/models/gold/mart_data_quality.sql +176 -0
  344. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/models/gold/mart_inventory.sql +19 -0
  345. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/models/silver/inventory_level.sql +84 -0
  346. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/models/silver/inventory_level__reject.sql +132 -0
  347. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/models/silver/stock_level_matches_snapshot__reconcile.sql +49 -0
  348. bloomery-0.1.0/tests/golden/semi_additive_inventory/sqlmesh/duckdb/replay/inventory_level.sql +282 -0
  349. bloomery-0.1.0/tests/golden/step_resolution/sqlmesh/duckdb/audits/step_customer_xref_canonical_id_references_customer.sql +18 -0
  350. bloomery-0.1.0/tests/golden/step_resolution/sqlmesh/duckdb/models/silver/customer.py +51 -0
  351. bloomery-0.1.0/tests/golden/step_resolution/sqlmesh/duckdb/models/silver/customer_raw.sql +16 -0
  352. bloomery-0.1.0/tests/golden/step_resolution/sqlmesh/duckdb/models/silver/customer_xref.py +60 -0
  353. bloomery-0.1.0/tests/golden/test_cube.py +59 -0
  354. bloomery-0.1.0/tests/golden/test_dbt_postgres.py +48 -0
  355. bloomery-0.1.0/tests/golden/test_metricflow_manifest.py +37 -0
  356. bloomery-0.1.0/tests/golden/test_spec_schemas.py +44 -0
  357. bloomery-0.1.0/tests/golden/test_sqlmesh_dialects.py +49 -0
  358. bloomery-0.1.0/tests/golden/test_sqlmesh_duckdb.py +91 -0
  359. bloomery-0.1.0/tests/property/__init__.py +0 -0
  360. bloomery-0.1.0/tests/property/test_compile_properties.py +190 -0
  361. bloomery-0.1.0/tests/property/test_conservation.py +204 -0
  362. bloomery-0.1.0/tests/property/test_guardrail_properties.py +45 -0
  363. bloomery-0.1.0/tests/property/test_mart_properties.py +73 -0
  364. bloomery-0.1.0/tests/property/test_metricflow_properties.py +58 -0
  365. bloomery-0.1.0/tests/property/test_parse_properties.py +342 -0
  366. bloomery-0.1.0/tests/property/test_plan_properties.py +141 -0
  367. bloomery-0.1.0/tests/property/test_planner_properties.py +268 -0
  368. bloomery-0.1.0/tests/property/test_schema_agreement.py +454 -0
  369. bloomery-0.1.0/tests/support/__init__.py +0 -0
  370. bloomery-0.1.0/tests/support/chaos.py +178 -0
  371. bloomery-0.1.0/tests/support/compiling.py +99 -0
  372. bloomery-0.1.0/tests/support/cube.py +213 -0
  373. bloomery-0.1.0/tests/support/dirty.py +308 -0
  374. bloomery-0.1.0/tests/support/docs_claims.py +89 -0
  375. bloomery-0.1.0/tests/support/equivalence.py +164 -0
  376. bloomery-0.1.0/tests/support/execution.py +245 -0
  377. bloomery-0.1.0/tests/support/identity.py +180 -0
  378. bloomery-0.1.0/tests/support/ir_factory.py +176 -0
  379. bloomery-0.1.0/tests/support/mart_permutations.py +33 -0
  380. bloomery-0.1.0/tests/support/plan_ir.py +219 -0
  381. bloomery-0.1.0/tests/support/planning.py +131 -0
  382. bloomery-0.1.0/tests/support/precedence.py +212 -0
  383. bloomery-0.1.0/tests/support/quality_rules.py +80 -0
  384. bloomery-0.1.0/tests/support/reconcile.py +84 -0
  385. bloomery-0.1.0/tests/support/steps.py +139 -0
  386. bloomery-0.1.0/tests/unit/__init__.py +0 -0
  387. bloomery-0.1.0/tests/unit/test_changelog_release.py +228 -0
  388. bloomery-0.1.0/tests/unit/test_cli.py +852 -0
  389. bloomery-0.1.0/tests/unit/test_compile.py +38 -0
  390. bloomery-0.1.0/tests/unit/test_coverage_floors_guard.py +271 -0
  391. bloomery-0.1.0/tests/unit/test_determinism_guard.py +214 -0
  392. bloomery-0.1.0/tests/unit/test_dialects/__init__.py +0 -0
  393. bloomery-0.1.0/tests/unit/test_dialects/test_base.py +131 -0
  394. bloomery-0.1.0/tests/unit/test_dialects/test_duckdb.py +54 -0
  395. bloomery-0.1.0/tests/unit/test_dialects/test_postgres.py +79 -0
  396. bloomery-0.1.0/tests/unit/test_dialects/test_trino.py +63 -0
  397. bloomery-0.1.0/tests/unit/test_docs_floor.py +361 -0
  398. bloomery-0.1.0/tests/unit/test_docs_snippets.py +115 -0
  399. bloomery-0.1.0/tests/unit/test_emit/__init__.py +0 -0
  400. bloomery-0.1.0/tests/unit/test_emit/test_audit_vocabulary.py +137 -0
  401. bloomery-0.1.0/tests/unit/test_emit/test_base.py +121 -0
  402. bloomery-0.1.0/tests/unit/test_emit/test_cube.py +379 -0
  403. bloomery-0.1.0/tests/unit/test_emit/test_currency_convert.py +109 -0
  404. bloomery-0.1.0/tests/unit/test_emit/test_dbt.py +472 -0
  405. bloomery-0.1.0/tests/unit/test_emit/test_metricflow.py +474 -0
  406. bloomery-0.1.0/tests/unit/test_emit/test_quality_artifacts.py +745 -0
  407. bloomery-0.1.0/tests/unit/test_emit/test_quality_mart.py +384 -0
  408. bloomery-0.1.0/tests/unit/test_emit/test_sqlmesh.py +373 -0
  409. bloomery-0.1.0/tests/unit/test_error_suggestions.py +242 -0
  410. bloomery-0.1.0/tests/unit/test_errors.py +198 -0
  411. bloomery-0.1.0/tests/unit/test_evidence.py +398 -0
  412. bloomery-0.1.0/tests/unit/test_fixtures.py +221 -0
  413. bloomery-0.1.0/tests/unit/test_guardrails/__init__.py +0 -0
  414. bloomery-0.1.0/tests/unit/test_guardrails/test_additivity.py +170 -0
  415. bloomery-0.1.0/tests/unit/test_guardrails/test_arithmetic.py +215 -0
  416. bloomery-0.1.0/tests/unit/test_guardrails/test_asserts.py +207 -0
  417. bloomery-0.1.0/tests/unit/test_guardrails/test_conflict.py +59 -0
  418. bloomery-0.1.0/tests/unit/test_guardrails/test_grain.py +189 -0
  419. bloomery-0.1.0/tests/unit/test_guardrails/test_operands.py +99 -0
  420. bloomery-0.1.0/tests/unit/test_guardrails/test_quality.py +1040 -0
  421. bloomery-0.1.0/tests/unit/test_guardrails/test_stage.py +304 -0
  422. bloomery-0.1.0/tests/unit/test_import_contracts.py +96 -0
  423. bloomery-0.1.0/tests/unit/test_ir/__init__.py +0 -0
  424. bloomery-0.1.0/tests/unit/test_ir/test_fingerprint.py +238 -0
  425. bloomery-0.1.0/tests/unit/test_ir/test_lower.py +38 -0
  426. bloomery-0.1.0/tests/unit/test_ir/test_nodes.py +194 -0
  427. bloomery-0.1.0/tests/unit/test_marts/__init__.py +0 -0
  428. bloomery-0.1.0/tests/unit/test_marts/test_asserts.py +269 -0
  429. bloomery-0.1.0/tests/unit/test_marts/test_flatten.py +960 -0
  430. bloomery-0.1.0/tests/unit/test_metricflow_canary.py +135 -0
  431. bloomery-0.1.0/tests/unit/test_naming.py +37 -0
  432. bloomery-0.1.0/tests/unit/test_package.py +91 -0
  433. bloomery-0.1.0/tests/unit/test_plan/__init__.py +0 -0
  434. bloomery-0.1.0/tests/unit/test_plan/test_diff.py +780 -0
  435. bloomery-0.1.0/tests/unit/test_plan/test_evolution.py +189 -0
  436. bloomery-0.1.0/tests/unit/test_plan/test_model.py +49 -0
  437. bloomery-0.1.0/tests/unit/test_plan/test_quality_changes.py +701 -0
  438. bloomery-0.1.0/tests/unit/test_plan/test_step_changes.py +161 -0
  439. bloomery-0.1.0/tests/unit/test_planner/__init__.py +0 -0
  440. bloomery-0.1.0/tests/unit/test_planner/test_coverage.py +236 -0
  441. bloomery-0.1.0/tests/unit/test_planner/test_filters.py +364 -0
  442. bloomery-0.1.0/tests/unit/test_planner/test_metricflow_planner.py +328 -0
  443. bloomery-0.1.0/tests/unit/test_planner/test_names.py +199 -0
  444. bloomery-0.1.0/tests/unit/test_planner/test_parse.py +517 -0
  445. bloomery-0.1.0/tests/unit/test_planner/test_request.py +283 -0
  446. bloomery-0.1.0/tests/unit/test_planner/test_row_policy.py +150 -0
  447. bloomery-0.1.0/tests/unit/test_purity_guard.py +159 -0
  448. bloomery-0.1.0/tests/unit/test_quality/__init__.py +0 -0
  449. bloomery-0.1.0/tests/unit/test_quality/test_coverage.py +311 -0
  450. bloomery-0.1.0/tests/unit/test_quality/test_dedupe_and_reject.py +184 -0
  451. bloomery-0.1.0/tests/unit/test_quality/test_edges.py +214 -0
  452. bloomery-0.1.0/tests/unit/test_quality/test_expression_scope.py +239 -0
  453. bloomery-0.1.0/tests/unit/test_quality/test_flags.py +181 -0
  454. bloomery-0.1.0/tests/unit/test_quality/test_lower.py +358 -0
  455. bloomery-0.1.0/tests/unit/test_quality/test_mart.py +148 -0
  456. bloomery-0.1.0/tests/unit/test_quality/test_predicates.py +673 -0
  457. bloomery-0.1.0/tests/unit/test_quality/test_reconcile.py +200 -0
  458. bloomery-0.1.0/tests/unit/test_quality/test_repair.py +338 -0
  459. bloomery-0.1.0/tests/unit/test_quality/test_text_rules.py +273 -0
  460. bloomery-0.1.0/tests/unit/test_resolve/__init__.py +0 -0
  461. bloomery-0.1.0/tests/unit/test_resolve/test_build.py +283 -0
  462. bloomery-0.1.0/tests/unit/test_resolve/test_graph.py +137 -0
  463. bloomery-0.1.0/tests/unit/test_resolve/test_metrics.py +75 -0
  464. bloomery-0.1.0/tests/unit/test_resolve/test_order.py +107 -0
  465. bloomery-0.1.0/tests/unit/test_resolve/test_reach.py +116 -0
  466. bloomery-0.1.0/tests/unit/test_resolve/test_recipes.py +132 -0
  467. bloomery-0.1.0/tests/unit/test_resolve/test_refs.py +188 -0
  468. bloomery-0.1.0/tests/unit/test_resolve/test_resolution.py +84 -0
  469. bloomery-0.1.0/tests/unit/test_rfc_corpus_guard.py +313 -0
  470. bloomery-0.1.0/tests/unit/test_runtime/__init__.py +0 -0
  471. bloomery-0.1.0/tests/unit/test_runtime/test_hydration.py +175 -0
  472. bloomery-0.1.0/tests/unit/test_runtime/test_sql_client.py +52 -0
  473. bloomery-0.1.0/tests/unit/test_schema.py +281 -0
  474. bloomery-0.1.0/tests/unit/test_signature_closure.py +280 -0
  475. bloomery-0.1.0/tests/unit/test_spec/__init__.py +0 -0
  476. bloomery-0.1.0/tests/unit/test_spec/test_catalog.py +160 -0
  477. bloomery-0.1.0/tests/unit/test_spec/test_common.py +75 -0
  478. bloomery-0.1.0/tests/unit/test_spec/test_document_versions.py +122 -0
  479. bloomery-0.1.0/tests/unit/test_spec/test_entity.py +215 -0
  480. bloomery-0.1.0/tests/unit/test_spec/test_mapping.py +182 -0
  481. bloomery-0.1.0/tests/unit/test_spec/test_marts.py +134 -0
  482. bloomery-0.1.0/tests/unit/test_spec/test_metrics.py +107 -0
  483. bloomery-0.1.0/tests/unit/test_spec/test_project.py +177 -0
  484. bloomery-0.1.0/tests/unit/test_spec/test_quality.py +674 -0
  485. bloomery-0.1.0/tests/unit/test_spec/test_relation_names.py +97 -0
  486. bloomery-0.1.0/tests/unit/test_spec/test_steps.py +198 -0
  487. bloomery-0.1.0/tests/unit/test_steps/__init__.py +0 -0
  488. bloomery-0.1.0/tests/unit/test_steps/test_contract.py +267 -0
  489. bloomery-0.1.0/tests/unit/test_steps/test_dbt_and_cube_emission.py +217 -0
  490. bloomery-0.1.0/tests/unit/test_steps/test_emission.py +565 -0
  491. bloomery-0.1.0/tests/unit/test_steps/test_identity_demo.py +242 -0
  492. bloomery-0.1.0/tests/unit/test_steps/test_lowering.py +540 -0
  493. bloomery-0.1.0/tests/unit/test_steps/test_macro_fields.py +414 -0
  494. bloomery-0.1.0/tests/unit/test_steps/test_manifest_and_registry.py +271 -0
  495. bloomery-0.1.0/tests/unit/test_steps/test_splice.py +66 -0
  496. bloomery-0.1.0/tests/unit/test_steps/test_step_canonicals.py +216 -0
  497. bloomery-0.1.0/tests/unit/test_steps/test_step_entities.py +125 -0
  498. bloomery-0.1.0/tests/unit/test_tenant_guard.py +56 -0
  499. bloomery-0.1.0/tests/unit/test_total_lookups.py +81 -0
  500. bloomery-0.1.0/tests/unit/test_transforms/__init__.py +0 -0
  501. bloomery-0.1.0/tests/unit/test_transforms/test_builtins.py +183 -0
  502. bloomery-0.1.0/tests/unit/test_transforms/test_registry.py +152 -0
  503. bloomery-0.1.0/tests/unit/test_typing/__init__.py +0 -0
  504. bloomery-0.1.0/tests/unit/test_typing/test_check.py +229 -0
  505. bloomery-0.1.0/tests/unit/test_typing/test_types.py +134 -0
  506. bloomery-0.1.0/uv.lock +3043 -0
@@ -0,0 +1,245 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
219
+
220
+ # ....................... #
221
+ # bloomery-specific (RFC 0001)
222
+
223
+ # hatch-vcs generated version file
224
+ src/bloomery/_version.py
225
+
226
+ # Docs build output
227
+ pages/site/
228
+ pages/.cache/
229
+
230
+ # Tooling state
231
+ .benchmarks
232
+ .just/
233
+ junit.xml
234
+ # Per-interpreter results the CI test matrix writes (junit-3.12.xml, …).
235
+ junit-*.xml
236
+ coverage-data/
237
+ .envrc
238
+ .claude/projects/
239
+
240
+ # NOTE: rfcs/ is deliberately committed here — the RFC corpus is a deliverable.
241
+
242
+ # Stray warehouse files from local SQLMesh/DuckDB runs — the e2e tier builds
243
+ # its own under tmp_path and never writes into the repo.
244
+ *.duckdb
245
+ *.duckdb.wal
@@ -0,0 +1,154 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-08-15
11
+
12
+ First release. Everything bloomery does is new here, so this section is one `Added` —
13
+ `Changed`, `Deprecated`, `Removed`, `Fixed` and `Security` describe movement away from a
14
+ version somebody could have installed, and there is not one yet. They begin at 0.2.0.
15
+
16
+ From this tag the [stability promises](https://morzecrew.github.io/bloomery/reference/stability/)
17
+ bind: SemVer over the Python API, per-kind versioning over spec YAML, and emitted
18
+ artifacts explicitly **not** stable across bloomery versions.
19
+
20
+ ### Added
21
+
22
+ **The compiler**
23
+
24
+ - `compile_project(project, *, target, dialect, naming=None, catalog=None, steps=EMPTY_REGISTRY)`
25
+ — declarative specs to target artifacts as one pure function. No filesystem, no
26
+ network, no clock, no randomness: the same specs produce byte-identical artifacts
27
+ across machines, processes and `PYTHONHASHSEED` values.
28
+ - **Six spec document kinds**, each strict YAML that self-identifies by its version key:
29
+ Catalog (`catalog_version`), EntityModel (`spec_version`), Mapping (`mapping_version`),
30
+ MetricSet (`metrics_version`), MartSet (`marts_version`) and StepSet (`steps_version`).
31
+ Unknown keys, duplicate YAML keys and grammar violations are refused, batched per
32
+ document with a source path each. A version bloomery does not implement is refused
33
+ rather than read as one it does.
34
+ - Deterministic intermediate representation with a `blm1:` content fingerprint
35
+ (`build_project_ir`, `project_fingerprint`), stamped into every artifact header.
36
+ `bloomery_ir_version` is **5**; it covers each node's field names and count, so an IR
37
+ shape change moves every fingerprint by construction.
38
+ - A closed whitelist of 24 typed mapping transforms with a compile-time typecheck of
39
+ every chain, decimal precision and scale tracked through arithmetic, and
40
+ `register_transform` for vetted extensions.
41
+ - Resolution (`resolve`): cross-spec reference validation, recorded-recipe validation,
42
+ cycle detection, and metric reachability naming the specific missing leaf.
43
+ `UnreachableMetric.via` names the chain when a metric is blocked *through* another one.
44
+
45
+ **Guardrails**
46
+
47
+ - Fail-closed unit, tax-basis, currency, grain and additivity checks; mart fan-out and
48
+ grain protection; `assert:` clauses lowered to target-native audits. Every violation is
49
+ a typed error with a source path, and stages batch so a spec is fixed in one round trip.
50
+ - Two constructs that used to compile clean and could not be right are refused:
51
+ `HistoricalFanout` for a mart flattening an `scd: type2` dimension with no validity
52
+ predicate (each base row multiplied by that key's version count, with every declared
53
+ cardinality still honest), and `UnsupportedByTarget` for the `convert` transform, which
54
+ lowered to a `CONVERT_CURRENCY` call no engine defines. `convert` stays registered and
55
+ typechecked; currency conversion needs a dated rate relation bloomery does not model.
56
+
57
+ **Data quality**
58
+
59
+ - Cleansing as spec surface: a closed rule catalogue (`coercible`, `not_null`, `range`,
60
+ `length`, `pattern`, `in_enum`, `in_set`, `unique`, `normalize`, `charset`), entity row
61
+ rules (`expression`, `referential`), `dedupe:`, `quarantine:`, document-level
62
+ `reconcile:`, and cross-entity `coverage:` checks. Every rule carries an explicit
63
+ `on_fail` — `flag`, `quarantine`, `fail` or `repair` — and rules evaluate under a
64
+ strict three-valued discipline, so a NULL-involved comparison never fires.
65
+ - `pattern` speaks a portable regex allowlist, refused at parse with the construct named;
66
+ `range` bounds are exact (int, decimal, or a string carrying an exact decimal or ISO
67
+ date/timestamp); `charset` declares admissible characters as `U+` codepoints.
68
+ - One replayable `<entity>__reject` table per entity with a `reject_id` recomputable from
69
+ the row, a replay artifact that re-runs the current mapping under the pipeline's own
70
+ dedupe order, `retention:` and `redact:`. bloomery emits the artifact and never runs it.
71
+ - `gold.mart_data_quality` — an ordinary mart with one row per rule evaluation plus an
72
+ accounting row per entity, so quarantine rate is a plain `MetricRequest`. Five reserved
73
+ metrics come with it.
74
+ - Every silver model projects `_quality_flags` and `_quality_ok`; a mart over a
75
+ rule-carrying base flattens them into a `has_quality_flags` dimension.
76
+
77
+ **Steps: referenced implementations**
78
+
79
+ - A project may wire platform-owned steps through a `steps_version: 1` document —
80
+ `use: ref@version`, input/output bindings, parameters within the manifest's declared
81
+ bounds, `expression` quality rules on outputs, and `canonical:` links so metrics and
82
+ `reconcile` can read a step output. Manifests reach the compiler as a frozen
83
+ `StepRegistry` passed to `compile_project(..., steps=…)`: bloomery reads no step files
84
+ and has no dynamic loading path, so a spec can never name code to load.
85
+ - Three tiers emit — `sql_macro` splices into the consuming SELECT, `sql_model` emits an
86
+ ordinary model, and `python_model` emits one generated wrapper per declared output,
87
+ each carrying a non-optional `assert_step_contract` call. Step outputs are entities:
88
+ a mart may reference one exactly as it would any silver entity, and `plan()` diffs them.
89
+ - `bloomery.steps.assert_step_contract` — the run-time contract, and the only bloomery
90
+ name intended for import outside compilation. It imports nothing but `bloomery.errors`.
91
+
92
+ **The gold layer and the emitters**
93
+
94
+ - Wide marts: relationship flattening with mandatory prefixes, role-playing date
95
+ dimensions (`ordered_month`, `shipped_month`, …), a generated `dim_date` owned by the
96
+ catalog, and aggregate `assert:` clauses lowering to target-native audits.
97
+ - Emit targets for **SQLMesh** (models, audits, native SCD2, reject/replay, quality
98
+ audits), **dbt** (models through `ref()`/`source()`, sources, snapshots, schema tests,
99
+ a self-contained expression-test macro) and **Cube** (cubes and views with additivity
100
+ metadata, ratios as calculated measures), rendering over **DuckDB**, **Trino** and
101
+ **PostgreSQL**. `register_emitter` adds extension targets. Where a target cannot express
102
+ a declaration it raises `UnsupportedByTarget` rather than dropping it silently.
103
+
104
+ **Request-time planning**
105
+
106
+ - `MetricFlowPlanner`: a structured `MetricRequest` becomes SQL over a wide mart plus
107
+ typed columns, warnings, a deterministic explanation and a fingerprint — refusing
108
+ unknown members, cross-grain requests and ambiguous dimensions instead of guessing.
109
+ MetricFlow is embedded and render-only, never connected to a database. Bind result rows
110
+ by `ColumnDescriptor.sql_alias`; display `name`.
111
+ - Filters are typed CNF clauses (`Predicate` / `AnyOf` — implicit AND, one level of OR),
112
+ with `RowPolicy` for row-level scoping and `parse_filter_json` / `parse_sort_json` /
113
+ `parse_page_json` as the Mongo-flavoured JSON front door. Unsupported constructs raise
114
+ `UnsupportedFilter` with a stable reason code from the closed, drift-guarded set
115
+ exported as `bloomery.planner.KNOWN_UNSUPPORTED`.
116
+ - `LruManifestHydrator` / `HydrationKey`: in-process manifest hydration keyed by spec
117
+ fingerprint and library versions, with an optional caller-owned byte store.
118
+
119
+ **Assessing and evolving a spec**
120
+
121
+ - `evaluate(project) -> SpecEvidence` — everything knowable about a spec without touching
122
+ data, as one value: reachable metrics, unreachable ones with the missing leaf, batched
123
+ refusals with source paths, mart shapes, entities, fingerprint. **Refusals are the
124
+ return value**, and analysis that completed before the refusal comes back with them.
125
+ `InvariantViolated` and every programming error still propagate.
126
+ - `plan()` — every change between two compiled versions classified as additive, widening,
127
+ rename, restating or breaking, with backfill scope, replay scope for the reject tables a
128
+ change invalidates, downstream metric impact and an enforced expand/contract workflow.
129
+ - Structured fix suggestions on five refusals: `UnknownMember.did_you_mean`,
130
+ `UnreachableAtGrain.covering_marts`, `GrainViolation.offending_measures`,
131
+ `UnknownStep.available_versions`, `UnsupportedFilter.nearest_supported`. Always present
132
+ — `()` or `None` when there is nothing to suggest, never absent and never fabricated.
133
+
134
+ **Surfaces**
135
+
136
+ - A total error hierarchy rooted at `BloomeryError`: every failure is typed, carries a
137
+ source path into the offending spec node, and is documented in the errors reference.
138
+ - **A command line** — `bloomery compile|plan|resolve|explain|schema|fingerprint`, plus
139
+ `bloomery --version`. Each command is a thin argument shell over one public function;
140
+ `--format json` emits the same values the Python API returns. A refusal exits `1` and a
141
+ usage error `2`, so a pipeline can tell "your spec is wrong" from "your command is
142
+ wrong". Nothing is executed: `bloomery run` does not exist.
143
+ - **JSON Schema per spec kind** — `spec_json_schema(kind)`, `all_spec_schemas()`, and
144
+ `bloomery schema --out DIR`. Generated from the Pydantic models so they cannot drift
145
+ from the parser, with every closed set enumerated. Also published at
146
+ `https://morzecrew.github.io/bloomery/schemas/v1/<kind>.json`.
147
+ - `bloomery.__all__` is **closed over its own signatures**: every type named in a public
148
+ signature is importable from the root, enforced by a test that walks the whole surface.
149
+ `bloomery.__version__` reports the installed release.
150
+ - Documentation: get-started, concepts, how-to guides for every target and the planner,
151
+ full spec/transform/error/API/stability references, and a runnable `examples/quickstart/`.
152
+
153
+ [Unreleased]: https://github.com/morzecrew/bloomery/compare/v0.1.0...HEAD
154
+ [0.1.0]: https://github.com/morzecrew/bloomery/releases/tag/v0.1.0
bloomery-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Morze Technologies
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,224 @@
1
+ Metadata-Version: 2.5
2
+ Name: bloomery
3
+ Version: 0.1.0
4
+ Summary: Entity-first spec compiler: declarative entity/mapping/metric specs → SQLMesh, dbt, and Cube artifacts
5
+ Project-URL: homepage, https://github.com/morzecrew/bloomery
6
+ Project-URL: documentation, https://morzecrew.github.io/bloomery/
7
+ Project-URL: changelog, https://github.com/morzecrew/bloomery/blob/main/CHANGELOG.md
8
+ Project-URL: issues, https://github.com/morzecrew/bloomery/issues
9
+ Author-email: Lev Litvinov <misery7100@gmail.com>
10
+ Maintainer-email: Lev Litvinov <misery7100@gmail.com>
11
+ License: MIT License
12
+
13
+ Copyright (c) 2026 Morze Technologies
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE.
32
+ License-File: LICENSE
33
+ Keywords: analytics,compiler,cube,data-engineering,dbt,semantic-layer,sqlglot,sqlmesh
34
+ Classifier: Development Status :: 3 - Alpha
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.12
38
+ Classifier: Programming Language :: Python :: 3.13
39
+ Classifier: Programming Language :: Python :: 3.14
40
+ Classifier: Topic :: Software Development :: Code Generators
41
+ Classifier: Topic :: Software Development :: Libraries
42
+ Classifier: Typing :: Typed
43
+ Requires-Python: <3.15,>=3.12
44
+ Requires-Dist: jinja2>=3.1
45
+ Requires-Dist: metricflow==0.211.*
46
+ Requires-Dist: pydantic>=2.9
47
+ Requires-Dist: pyyaml>=6
48
+ Requires-Dist: sqlglot<31,>=30.8.0
49
+ Description-Content-Type: text/markdown
50
+
51
+ # bloomery
52
+
53
+ **Entity-first spec compiler: declarative entity/mapping/metric specs, compiled deterministically into SQLMesh, dbt, and Cube artifacts.**
54
+
55
+ ## What it is
56
+
57
+ bloomery is a pure function library. You hand it declarative specs — a catalog, entities,
58
+ mappings, metrics, marts, and optionally steps — and it compiles them into ready-to-run
59
+ artifacts for SQLMesh, dbt, and Cube: models, audits, and semantic-layer definitions.
60
+ The same specs also serve metric queries at request time: a structured `MetricRequest`
61
+ becomes SQL over a wide mart, planned by an embedded, render-only MetricFlow.
62
+
63
+ - **Deterministic** — same specs in, byte-identical artifacts out, across machines,
64
+ processes, and hash seeds. No clocks, no randomness, no environment reads.
65
+ - **Fail-closed guardrails** — grain fan-out, additivity violations, and contract breaks
66
+ are compile errors with named reasons, not silent wrong numbers downstream.
67
+ - **Reviewable** — emitted artifacts are stable-sorted, pretty-printed text, so a diff of
68
+ the output is a faithful diff of the semantic change.
69
+
70
+ ## What it is not
71
+
72
+ - It does **not execute SQL** — it emits artifacts and plans for engines and frameworks
73
+ that do.
74
+ - It does **no orchestration** — scheduling, backfills, and deployment belong to SQLMesh,
75
+ dbt, or whatever runs the artifacts.
76
+ - It contains **no LLM** — specs are authored by people (or by tools upstream of this
77
+ library); compilation is deterministic all the way down.
78
+
79
+ ## Quick start
80
+
81
+ ```bash
82
+ uv add bloomery
83
+ ```
84
+
85
+ Compile specs into SQLMesh artifacts (the library never touches the filesystem —
86
+ writing is your loop):
87
+
88
+ ```python
89
+ from bloomery import Target, compile_project, load_catalog, load_project
90
+
91
+ catalog = load_catalog(catalog_yaml)
92
+ project = load_project(
93
+ {
94
+ "entity_model.yaml": entities_yaml,
95
+ "mapping_orders.yaml": mapping_yaml,
96
+ "metrics.yaml": metrics_yaml,
97
+ "marts.yaml": marts_yaml,
98
+ }
99
+ )
100
+
101
+ artifacts = compile_project(project, target=Target.SQLMESH, dialect="duckdb", catalog=catalog)
102
+ for artifact in artifacts:
103
+ print(artifact.path) # write artifact.content wherever your repo keeps models
104
+ ```
105
+
106
+ Or from a shell — the CLI is a thin argument shell over exactly these functions, and the
107
+ only part of the package that touches a filesystem:
108
+
109
+ ```bash
110
+ bloomery compile specs/ --target sqlmesh --dialect duckdb --out out/
111
+ bloomery resolve specs/ # what is computable, what is missing, what was refused
112
+ bloomery schema --out schemas/ # JSON Schema per spec kind, for editors and validators
113
+ ```
114
+
115
+ A refusal exits `1` and a bad invocation exits `2`, so a pipeline can tell "your spec is
116
+ wrong" from "your command is wrong". Nothing is executed: `bloomery run` does not exist.
117
+
118
+ Assess a spec before it compiles — refusals come back as a **value**, alongside whatever
119
+ analysis completed before them, so a draft mid-edit still reports what it would give you:
120
+
121
+ ```python
122
+ from bloomery import Stage, evaluate
123
+
124
+ evidence = evaluate(project, catalog=catalog)
125
+ evidence.stage_reached # read this first: at any stage but COMPLETE the rest is a prefix
126
+ evidence.reachable # ('gross_revenue', 'order_count', …)
127
+ evidence.unreachable # margin, blocked on 'cogs' — the specific leaf, not a summary
128
+ evidence.refusals # each with its own source path into the spec that caused it
129
+ ```
130
+
131
+ Plan a metric request over the mart those specs declared — SQL out, nothing executed:
132
+
133
+ ```python
134
+ from bloomery import LruManifestHydrator, MetricFlowPlanner, MetricRequest, build_project_ir
135
+ from bloomery.naming import DefaultNaming
136
+
137
+ naming = DefaultNaming()
138
+ planner = MetricFlowPlanner(LruManifestHydrator(naming), naming=naming)
139
+ plan = planner.plan(
140
+ build_project_ir(project, catalog=catalog),
141
+ MetricRequest(metrics=("revenue",), dimensions=("ordered_month",)),
142
+ dialect="duckdb",
143
+ )
144
+ print(plan.sql)
145
+ print(plan.explanation.render())
146
+ ```
147
+
148
+ Filters are typed CNF clauses (`Predicate` / `AnyOf` — implicit AND, one level of OR), and
149
+ `bloomery.planner.parse_filter_json` is a public front door for the Mongo-flavoured JSON
150
+ grammar (`$and`/`$or`/`$not`, field maps): it normalizes (De Morgan → complement inversion
151
+ → capped CNF) before refusing, and refuses only from the closed, drift-guarded list
152
+ exported as `bloomery.planner.KNOWN_UNSUPPORTED`:
153
+
154
+ ```python
155
+ from bloomery.planner import parse_filter_json
156
+
157
+ filters = parse_filter_json(
158
+ {
159
+ "customer_id": {"$neq": "internal"},
160
+ "$or": [{"ordered_month": {"$gte": "2024-01-01"}}, {"ordered_month": "2023-12-01"}],
161
+ }
162
+ ) # → (Predicate(…), AnyOf(…)) — pass straight to MetricRequest(filters=…)
163
+ ```
164
+
165
+ The runnable version of both snippets lives in
166
+ [`examples/quickstart/`](examples/quickstart/):
167
+
168
+ ```bash
169
+ uv run python examples/quickstart/run.py
170
+ ```
171
+
172
+ ## Status
173
+
174
+ **0.1.0** — the first release. Everything the library does ships behind the quality gate:
175
+ the spec layer over six document kinds, the deterministic IR, transforms and typecheck,
176
+ resolution, fail-closed guardrails, declarative data quality with quarantine and replay,
177
+ steps as referenced implementations, wide marts with role-playing dates, the
178
+ SQLMesh/dbt/Cube emitters over DuckDB/Trino/Postgres, the MetricFlow-backed planner with
179
+ manifest hydration, spec-diff planning, spec assessment, the CLI and the JSON Schema
180
+ export. Every test tier runs, including the Docker-backed engine matrix, the target e2e
181
+ tiers and the three-way equivalence tier.
182
+
183
+ From this release the promises in
184
+ [Stability](https://morzecrew.github.io/bloomery/reference/stability/) bind: per-kind
185
+ versioning over spec YAML (fully), SemVer over the Python API (breaking changes are
186
+ allowed in a minor below 1.0, but never silent), and emitted artifacts explicitly **not**
187
+ stable across versions — byte-reproducible for fixed inputs, which is determinism rather
188
+ than a cross-version promise. Pin the minor if you want the API to hold still.
189
+
190
+ Designs that have not yet landed live as RFCs in [`rfcs/`](rfcs/INDEX.md); code that
191
+ contradicts a live RFC is the bug, not the RFC. An RFC is retired once it ships — the
192
+ code, the tests and the documentation are the account of what bloomery already does.
193
+
194
+ ## Documentation
195
+
196
+ Full documentation is available at
197
+ [https://morzecrew.github.io/bloomery/](https://morzecrew.github.io/bloomery/):
198
+
199
+ - [Quickstart](https://morzecrew.github.io/bloomery/get-started/quickstart/) — specs to
200
+ compiled artifacts to a planned query.
201
+ - [Concepts](https://morzecrew.github.io/bloomery/concepts/specs-and-catalog/) — the
202
+ domain model, the compile pipeline, determinism, guardrails, wide marts.
203
+ - How-to guides — emit
204
+ [SQLMesh](https://morzecrew.github.io/bloomery/how-to/emit-sqlmesh/),
205
+ [Cube](https://morzecrew.github.io/bloomery/how-to/emit-cube/), or
206
+ [dbt](https://morzecrew.github.io/bloomery/how-to/emit-dbt/);
207
+ [plan a metric request](https://morzecrew.github.io/bloomery/how-to/plan-a-metric-request/);
208
+ [evolve a spec safely](https://morzecrew.github.io/bloomery/how-to/evolve-a-spec/).
209
+ - Reference —
210
+ [spec schemas](https://morzecrew.github.io/bloomery/reference/spec-schemas/),
211
+ [transforms](https://morzecrew.github.io/bloomery/reference/transforms/),
212
+ [errors](https://morzecrew.github.io/bloomery/reference/errors/),
213
+ [API](https://morzecrew.github.io/bloomery/reference/api/),
214
+ [stability](https://morzecrew.github.io/bloomery/reference/stability/).
215
+
216
+ ## Contributing
217
+
218
+ Contributions, issues, and feature requests are welcome.
219
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for details — including the RFC process for larger
220
+ changes.
221
+
222
+ ## Licence
223
+
224
+ bloomery is licensed under the MIT License — see [LICENSE](LICENSE) for details.