loom-kernel 0.3.0__tar.gz → 0.4.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 (560) hide show
  1. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/.github/workflows/release.yml +15 -10
  2. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/.gitignore +1 -0
  3. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/.readthedocs.yaml +6 -0
  4. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/CHANGELOG.md +2 -47
  5. loom_kernel-0.4.0/CHANGELOG_RELEASE.md +15 -0
  6. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/PKG-INFO +63 -2
  7. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/README.md +62 -1
  8. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/conf.py +1 -1
  9. loom_kernel-0.4.0/docs/etl/examples.md +29 -0
  10. loom_kernel-0.4.0/docs/etl/testing.md +65 -0
  11. loom_kernel-0.4.0/docs/getting-started/etl.md +136 -0
  12. loom_kernel-0.4.0/docs/getting-started/rest.md +424 -0
  13. loom_kernel-0.4.0/docs/guides/etl.md +559 -0
  14. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/index.rst +17 -12
  15. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/reference/api/etl.rst +1 -0
  16. loom_kernel-0.4.0/docs/rest/autocrud.md +166 -0
  17. loom_kernel-0.4.0/docs/rest/celery.md +538 -0
  18. loom_kernel-0.4.0/docs/rest/examples.md +642 -0
  19. loom_kernel-0.4.0/docs/rest/testing.md +67 -0
  20. loom_kernel-0.4.0/docs/rest/use-case-dsl.md +477 -0
  21. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/pyproject.toml +2 -2
  22. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/__init__.py +22 -0
  23. loom_kernel-0.4.0/src/loom/etl/backends/_historify/__init__.py +19 -0
  24. loom_kernel-0.4.0/src/loom/etl/backends/_historify/_common.py +43 -0
  25. loom_kernel-0.4.0/src/loom/etl/backends/_historify/_log.py +42 -0
  26. loom_kernel-0.4.0/src/loom/etl/backends/_historify/_ops.py +90 -0
  27. loom_kernel-0.4.0/src/loom/etl/backends/_historify/_snapshot.py +72 -0
  28. loom_kernel-0.4.0/src/loom/etl/backends/_historify/_transform.py +97 -0
  29. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/_write_policy.py +186 -19
  30. loom_kernel-0.4.0/src/loom/etl/backends/polars/_historify.py +192 -0
  31. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/_writer.py +102 -0
  32. loom_kernel-0.4.0/src/loom/etl/backends/spark/_historify.py +227 -0
  33. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/spark/_writer.py +127 -18
  34. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/compiler/_validators.py +3 -0
  35. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/compiler/_validators_step.py +180 -1
  36. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/__init__.py +28 -1
  37. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/target/__init__.py +47 -6
  38. loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/__init__.py +30 -0
  39. loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_builder.py +241 -0
  40. loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_enums.py +58 -0
  41. loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_errors.py +78 -0
  42. loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_report.py +27 -0
  43. loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_spec.py +69 -0
  44. loom_kernel-0.4.0/tests/unit/etl/backends/_historify_contract.py +885 -0
  45. loom_kernel-0.4.0/tests/unit/etl/backends/test_historify_common.py +52 -0
  46. loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_dtype.py +137 -0
  47. loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_historify_polars.py +212 -0
  48. loom_kernel-0.4.0/tests/unit/etl/backends/test_spark/test_historify_spark.py +238 -0
  49. loom_kernel-0.4.0/tests/unit/etl/backends/test_write_policy_historify.py +283 -0
  50. loom_kernel-0.4.0/tests/unit/etl/compiler/test_historify_validator.py +432 -0
  51. loom_kernel-0.4.0/tests/unit/etl/io/test_history_target.py +739 -0
  52. loom_kernel-0.4.0/tests/unit/etl/storage/test_route_build.py +146 -0
  53. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_module_contracts.py +20 -50
  54. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/uv.lock +1 -1
  55. loom_kernel-0.3.0/CHANGELOG_RELEASE.md +0 -60
  56. loom_kernel-0.3.0/tests/unit/etl/storage/test_route_build.py +0 -31
  57. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/.github/workflows/ci-main.yml +0 -0
  58. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/.github/workflows/ci-pr.yml +0 -0
  59. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/.github/workflows/docs.yml +0 -0
  60. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/.pre-commit-config.yaml +0 -0
  61. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/LICENSE +0 -0
  62. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/Makefile +0 -0
  63. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/codecov.yml +0 -0
  64. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/_static/.gitkeep +0 -0
  65. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/_static/custom.css +0 -0
  66. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/_static/logo-transparent.png +0 -0
  67. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/_static/logo.svg +0 -0
  68. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/architecture/adr/README.md +0 -0
  69. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/architecture/clean-architecture.md +0 -0
  70. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/architecture/overview.md +0 -0
  71. /loom_kernel-0.3.0/docs/guides/etl.md → /loom_kernel-0.4.0/docs/etl/pipelines.md +0 -0
  72. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/examples-repo/index.md +0 -0
  73. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/guides/autocrud.md +0 -0
  74. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/guides/celery.md +0 -0
  75. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/guides/fake-repo-examples.md +0 -0
  76. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/guides/quickstart.md +0 -0
  77. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/guides/use-case-dsl.md +0 -0
  78. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/reference/api/core.rst +0 -0
  79. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/reference/api/repository.rst +0 -0
  80. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/reference/api/rest.rst +0 -0
  81. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/reference/api/testing.rst +0 -0
  82. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/reference/index.rst +0 -0
  83. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/docs/requirements.txt +0 -0
  84. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/sonar-project.properties +0 -0
  85. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/__init__.py +0 -0
  86. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/celery/__init__.py +0 -0
  87. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/celery/auto.py +0 -0
  88. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/celery/bootstrap.py +0 -0
  89. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/celery/config.py +0 -0
  90. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/celery/constants.py +0 -0
  91. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/celery/event_loop.py +0 -0
  92. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/celery/runner.py +0 -0
  93. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/celery/service.py +0 -0
  94. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/backend/__init__.py +0 -0
  95. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/backend/core_model.py +0 -0
  96. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/backend/protocol.py +0 -0
  97. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/backend/sqlalchemy.py +0 -0
  98. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/bootstrap/__init__.py +0 -0
  99. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
  100. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/bootstrap/kernel.py +0 -0
  101. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/__init__.py +0 -0
  102. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/abc/__init__.py +0 -0
  103. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/abc/backend.py +0 -0
  104. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/abc/config.py +0 -0
  105. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/abc/dependency.py +0 -0
  106. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/codec.py +0 -0
  107. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/decorators.py +0 -0
  108. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/dependency.py +0 -0
  109. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/gateway.py +0 -0
  110. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/keys.py +0 -0
  111. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/repository.py +0 -0
  112. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/cache/serializer.py +0 -0
  113. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/command/__init__.py +0 -0
  114. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/command/adapter.py +0 -0
  115. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/command/base.py +0 -0
  116. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/command/field.py +0 -0
  117. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/command/introspection.py +0 -0
  118. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/config/__init__.py +0 -0
  119. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/config/errors.py +0 -0
  120. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/config/keys.py +0 -0
  121. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/config/loader.py +0 -0
  122. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/config/model.py +0 -0
  123. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/config/resolver.py +0 -0
  124. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/contracts/__init__.py +0 -0
  125. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/contracts/manifest.py +0 -0
  126. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/di/__init__.py +0 -0
  127. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/di/container.py +0 -0
  128. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/di/scope.py +0 -0
  129. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/discovery/__init__.py +0 -0
  130. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/discovery/_utils.py +0 -0
  131. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/discovery/base.py +0 -0
  132. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/discovery/interfaces.py +0 -0
  133. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/discovery/manifest.py +0 -0
  134. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/discovery/modules.py +0 -0
  135. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/engine/__init__.py +0 -0
  136. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/engine/compilable.py +0 -0
  137. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/engine/compiler.py +0 -0
  138. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/engine/events.py +0 -0
  139. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/engine/executor.py +0 -0
  140. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/engine/metrics.py +0 -0
  141. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/engine/plan.py +0 -0
  142. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/errors/__init__.py +0 -0
  143. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/errors/codes.py +0 -0
  144. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/errors/errors.py +0 -0
  145. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/job/__init__.py +0 -0
  146. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/job/callback.py +0 -0
  147. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/job/context.py +0 -0
  148. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/job/handle.py +0 -0
  149. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/job/job.py +0 -0
  150. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/job/service.py +0 -0
  151. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/logger/__init__.py +0 -0
  152. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/logger/abc.py +0 -0
  153. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/logger/config.py +0 -0
  154. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/logger/registry.py +0 -0
  155. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/logger/structlogger.py +0 -0
  156. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/__init__.py +0 -0
  157. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/base.py +0 -0
  158. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/enums.py +0 -0
  159. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/field.py +0 -0
  160. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/introspection.py +0 -0
  161. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/projection.py +0 -0
  162. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/relation.py +0 -0
  163. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/struct.py +0 -0
  164. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/timestamped.py +0 -0
  165. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/types.py +0 -0
  166. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/model/types_postgres.py +0 -0
  167. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/projection/__init__.py +0 -0
  168. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/projection/loaders.py +0 -0
  169. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/projection/runtime.py +0 -0
  170. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/__init__.py +0 -0
  171. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/abc/__init__.py +0 -0
  172. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/abc/query.py +0 -0
  173. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  174. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/abc/repository.py +0 -0
  175. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/mutation.py +0 -0
  176. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/registration.py +0 -0
  177. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/registry.py +0 -0
  178. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  179. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  180. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  181. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
  182. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  183. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  184. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  185. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  186. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  187. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  188. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  189. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
  190. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  191. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  192. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  193. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  194. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  195. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
  196. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  197. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  198. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/response/__init__.py +0 -0
  199. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/response/base.py +0 -0
  200. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/tracing/__init__.py +0 -0
  201. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/tracing/context.py +0 -0
  202. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/transport/__init__.py +0 -0
  203. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/transport/adapter.py +0 -0
  204. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/uow/__init__.py +0 -0
  205. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/uow/abc.py +0 -0
  206. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/uow/context.py +0 -0
  207. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/__init__.py +0 -0
  208. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/_predicates.py +0 -0
  209. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/compute.py +0 -0
  210. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/constants.py +0 -0
  211. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/factory.py +0 -0
  212. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/field_ref.py +0 -0
  213. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/invoker.py +0 -0
  214. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/keys.py +0 -0
  215. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/markers.py +0 -0
  216. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/registry.py +0 -0
  217. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/rule.py +0 -0
  218. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/core/use_case/use_case.py +0 -0
  219. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/__init__.py +0 -0
  220. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/_format_registry.py +0 -0
  221. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/_merge.py +0 -0
  222. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/_predicate.py +0 -0
  223. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  224. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  225. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  226. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/__init__.py +0 -0
  227. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  228. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  229. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  230. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/_reader.py +0 -0
  231. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  232. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  233. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/polars/provider.py +0 -0
  234. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  235. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  236. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  237. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  238. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  239. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/backends/spark/provider.py +0 -0
  240. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/checkpoint/__init__.py +0 -0
  241. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
  242. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  243. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
  244. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  245. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  246. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/checkpoint/_store.py +0 -0
  247. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/compiler/__init__.py +0 -0
  248. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/compiler/_binding.py +0 -0
  249. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/compiler/_compiler.py +0 -0
  250. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/compiler/_errors.py +0 -0
  251. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/compiler/_plan.py +0 -0
  252. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  253. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/_format.py +0 -0
  254. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/_read_options.py +0 -0
  255. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/_utils.py +0 -0
  256. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/_write_options.py +0 -0
  257. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  258. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  259. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  260. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  261. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
  262. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/source/__init__.py +0 -0
  263. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/source/_from.py +0 -0
  264. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/source/_specs.py +0 -0
  265. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/target/_file.py +0 -0
  266. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/target/_into.py +0 -0
  267. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
  268. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/target/_table.py +0 -0
  269. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  270. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/executor/__init__.py +0 -0
  271. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  272. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/executor/_executor.py +0 -0
  273. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/__init__.py +0 -0
  274. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/config.py +0 -0
  275. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/factory.py +0 -0
  276. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/observers/__init__.py +0 -0
  277. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/observers/_labels.py +0 -0
  278. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/observers/composite.py +0 -0
  279. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/observers/noop.py +0 -0
  280. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/observers/otel.py +0 -0
  281. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/observers/protocol.py +0 -0
  282. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/observers/structlog.py +0 -0
  283. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/recording/__init__.py +0 -0
  284. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/recording/_recorder.py +0 -0
  285. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/records.py +0 -0
  286. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/sinks/__init__.py +0 -0
  287. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/sinks/_protocol.py +0 -0
  288. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/sinks/_table.py +0 -0
  289. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/observability/sinks/_writer.py +0 -0
  290. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/pipeline/__init__.py +0 -0
  291. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/pipeline/_generics.py +0 -0
  292. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/pipeline/_params.py +0 -0
  293. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  294. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/pipeline/_process.py +0 -0
  295. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/pipeline/_sql.py +0 -0
  296. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/pipeline/_step.py +0 -0
  297. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  298. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runner/__init__.py +0 -0
  299. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runner/_providers.py +0 -0
  300. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runner/_wiring.py +0 -0
  301. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runner/config_loader.py +0 -0
  302. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runner/core.py +0 -0
  303. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runner/errors.py +0 -0
  304. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runner/filtering.py +0 -0
  305. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runtime/__init__.py +0 -0
  306. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/runtime/contracts.py +0 -0
  307. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/schema/__init__.py +0 -0
  308. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/schema/_contract.py +0 -0
  309. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/schema/_schema.py +0 -0
  310. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/storage/__init__.py +0 -0
  311. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/storage/_config.py +0 -0
  312. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/storage/_file_locator.py +0 -0
  313. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/storage/_locator.py +0 -0
  314. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/storage/routing.py +0 -0
  315. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/testing/__init__.py +0 -0
  316. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/testing/_result.py +0 -0
  317. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/testing/_runners.py +0 -0
  318. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/testing/_scenario.py +0 -0
  319. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/testing/_stubs.py +0 -0
  320. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/etl/testing/spark.py +0 -0
  321. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/prometheus/__init__.py +0 -0
  322. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/prometheus/adapter.py +0 -0
  323. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/prometheus/middleware.py +0 -0
  324. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/__init__.py +0 -0
  325. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/adapter.py +0 -0
  326. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/autocrud.py +0 -0
  327. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/compiler.py +0 -0
  328. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/constants.py +0 -0
  329. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/errors.py +0 -0
  330. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/fastapi/__init__.py +0 -0
  331. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/fastapi/app.py +0 -0
  332. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/fastapi/auto.py +0 -0
  333. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/fastapi/openapi.py +0 -0
  334. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/fastapi/response.py +0 -0
  335. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
  336. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/middleware.py +0 -0
  337. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/model.py +0 -0
  338. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/rest/rest_adapter.py +0 -0
  339. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/testing/__init__.py +0 -0
  340. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/testing/golden.py +0 -0
  341. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/testing/http_harness.py +0 -0
  342. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/testing/in_memory.py +0 -0
  343. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/testing/repository_harness.py +0 -0
  344. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/src/loom/testing/runner.py +0 -0
  345. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/__init__.py +0 -0
  346. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/conftest.py +0 -0
  347. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/golden/__init__.py +0 -0
  348. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/golden/baselines/.gitkeep +0 -0
  349. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/golden/outputs/.gitkeep +0 -0
  350. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/golden/plans/.gitkeep +0 -0
  351. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/helpers/__init__.py +0 -0
  352. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/__init__.py +0 -0
  353. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/celery_bootstrap/__init__.py +0 -0
  354. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +0 -0
  355. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +0 -0
  356. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +0 -0
  357. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/conftest.py +0 -0
  358. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/__init__.py +0 -0
  359. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/repository/__init__.py +0 -0
  360. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/repository/sqlalchemy/__init__.py +0 -0
  361. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
  362. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
  363. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +0 -0
  364. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/rest/__init__.py +0 -0
  365. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/rest/test_auto_interface_integration.py +0 -0
  366. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/rest/test_fastapi_app_integration.py +0 -0
  367. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/use_case/test_custom_repository_integration.py +0 -0
  368. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
  369. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/etl/__init__.py +0 -0
  370. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/etl/test_runner_integration.py +0 -0
  371. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/etl/test_runtime_contracts.py +0 -0
  372. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/__init__.py +0 -0
  373. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/__init__.py +0 -0
  374. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -0
  375. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/conf.manifest.yaml +0 -0
  376. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/conf.modules.yaml +0 -0
  377. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/conf.yaml +0 -0
  378. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/main.py +0 -0
  379. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/manifest.py +0 -0
  380. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/__init__.py +0 -0
  381. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/category/__init__.py +0 -0
  382. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/category/model.py +0 -0
  383. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
  384. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/interface.py +0 -0
  385. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/jobs.py +0 -0
  386. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/model.py +0 -0
  387. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/relations.py +0 -0
  388. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/repository.py +0 -0
  389. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/repository_contract.py +0 -0
  390. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/review/__init__.py +0 -0
  391. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/review/model.py +0 -0
  392. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
  393. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/schemas.py +0 -0
  394. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/use_cases.py +0 -0
  395. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/support/__init__.py +0 -0
  396. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/integration/support/logical_repo_fixtures.py +0 -0
  397. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/celery_bootstrap/__init__.py +0 -0
  398. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/celery_bootstrap/test_bootstrap.py +0 -0
  399. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/celery_bootstrap/test_event_loop.py +0 -0
  400. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/celery_jobs/__init__.py +0 -0
  401. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/celery_jobs/test_auto.py +0 -0
  402. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/celery_jobs/test_celery_service.py +0 -0
  403. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/celery_jobs/test_config.py +0 -0
  404. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/celery_jobs/test_runner.py +0 -0
  405. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/backend/__init__.py +0 -0
  406. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/backend/test_backend_compiler.py +0 -0
  407. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/bootstrap/__init__.py +0 -0
  408. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/bootstrap/test_bootstrap.py +0 -0
  409. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +0 -0
  410. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/bootstrap/test_kernel.py +0 -0
  411. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/cache/test_cached_repository.py +0 -0
  412. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/command/__init__.py +0 -0
  413. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/command/test_command_base.py +0 -0
  414. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/command/test_command_field.py +0 -0
  415. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/command/test_command_patch.py +0 -0
  416. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/command/test_introspection.py +0 -0
  417. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/config/__init__.py +0 -0
  418. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/config/test_config.py +0 -0
  419. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/di/__init__.py +0 -0
  420. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/di/test_container.py +0 -0
  421. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/discovery/test_manifest.py +0 -0
  422. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/engine/__init__.py +0 -0
  423. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/engine/test_compiler.py +0 -0
  424. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/engine/test_executor.py +0 -0
  425. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
  426. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/engine/test_executor_uow.py +0 -0
  427. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/engine/test_metrics.py +0 -0
  428. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/engine/test_plan.py +0 -0
  429. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/errors/__init__.py +0 -0
  430. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/errors/test_errors.py +0 -0
  431. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/job/__init__.py +0 -0
  432. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/job/conftest.py +0 -0
  433. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/job/test_callback.py +0 -0
  434. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/job/test_context.py +0 -0
  435. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/job/test_handle.py +0 -0
  436. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/job/test_inline_service.py +0 -0
  437. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/job/test_job.py +0 -0
  438. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/logger/test_registry.py +0 -0
  439. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/model/__init__.py +0 -0
  440. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/model/test_model.py +0 -0
  441. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/model/test_struct.py +0 -0
  442. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/model/test_timestamped.py +0 -0
  443. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/projection/test_runtime.py +0 -0
  444. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/repository/abc/conftest.py +0 -0
  445. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/repository/abc/test_query.py +0 -0
  446. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
  447. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
  448. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/repository/sqlalchemy/test_loaders.py +0 -0
  449. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +0 -0
  450. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
  451. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/tracing/__init__.py +0 -0
  452. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/tracing/test_context.py +0 -0
  453. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/uow/__init__.py +0 -0
  454. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
  455. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
  456. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
  457. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/use_case/__init__.py +0 -0
  458. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_compute.py +0 -0
  459. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_factory.py +0 -0
  460. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
  461. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_invoker.py +0 -0
  462. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_markers.py +0 -0
  463. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_rule.py +0 -0
  464. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_use_case.py +0 -0
  465. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/__init__.py +0 -0
  466. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/__init__.py +0 -0
  467. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/conftest.py +0 -0
  468. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_apply_schema.py +0 -0
  469. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_backend.py +0 -0
  470. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_file_writer.py +0 -0
  471. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_predicate_pushdown.py +0 -0
  472. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_reader_columns.py +0 -0
  473. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +0 -0
  474. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_step_execution.py +0 -0
  475. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_upsert_writer.py +0 -0
  476. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_polars/test_writer_to_frame.py +0 -0
  477. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_spark/__init__.py +0 -0
  478. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_spark/conftest.py +0 -0
  479. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_spark/test_dtype.py +0 -0
  480. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_spark/test_spark_apply_schema.py +0 -0
  481. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_spark/test_step_execution.py +0 -0
  482. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/backends/test_spark/test_writer_to_frame.py +0 -0
  483. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/checkpoint/__init__.py +0 -0
  484. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/checkpoint/backends/test_checkpoint_polars.py +0 -0
  485. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/checkpoint/test_checkpoint_paths.py +0 -0
  486. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/checkpoint/test_cleaners.py +0 -0
  487. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/checkpoint/test_store.py +0 -0
  488. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/__init__.py +0 -0
  489. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_catalog_validator.py +0 -0
  490. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_compiler.py +0 -0
  491. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_compiler_catalog.py +0 -0
  492. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_compiler_upsert.py +0 -0
  493. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_errors.py +0 -0
  494. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_errors_additional_factories.py +0 -0
  495. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_errors_runtime_factories.py +0 -0
  496. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_param_exprs_validator.py +0 -0
  497. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_plan_traversal.py +0 -0
  498. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_step_validator.py +0 -0
  499. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_structural.py +0 -0
  500. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_temp_validator.py +0 -0
  501. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/compiler/test_upsert_validator.py +0 -0
  502. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/conftest.py +0 -0
  503. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/io/__init__.py +0 -0
  504. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/io/test_source.py +0 -0
  505. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/io/test_source_json.py +0 -0
  506. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/io/test_source_options.py +0 -0
  507. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/io/test_target.py +0 -0
  508. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/io/test_utils.py +0 -0
  509. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/io/test_variants.py +0 -0
  510. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/pipeline/__init__.py +0 -0
  511. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/pipeline/test_pipeline_process.py +0 -0
  512. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/pipeline/test_proxy.py +0 -0
  513. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/pipeline/test_step.py +0 -0
  514. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/schema/__init__.py +0 -0
  515. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/schema/test_contract.py +0 -0
  516. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/schema/test_schema.py +0 -0
  517. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/schema/test_table.py +0 -0
  518. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/sql/__init__.py +0 -0
  519. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/sql/test_merge.py +0 -0
  520. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/sql/test_predicate.py +0 -0
  521. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/sql/test_predicate_dialect.py +0 -0
  522. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/sql/test_sql_runtime.py +0 -0
  523. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/storage/__init__.py +0 -0
  524. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/storage/test_backend_factory.py +0 -0
  525. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/storage/test_io_protocols.py +0 -0
  526. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/storage/test_locator.py +0 -0
  527. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/storage/test_observability_and_protocols.py +0 -0
  528. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/storage/test_schema_readers.py +0 -0
  529. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/storage/test_storage_config.py +0 -0
  530. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_config_loader.py +0 -0
  531. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_executor.py +0 -0
  532. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_format_registry.py +0 -0
  533. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_observer.py +0 -0
  534. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_observer_internals.py +0 -0
  535. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_public_api_discovery.py +0 -0
  536. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_record_schema_coverage.py +0 -0
  537. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_runner.py +0 -0
  538. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_runner_errors.py +0 -0
  539. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/test_spark_testing.py +0 -0
  540. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/testing/test_runners.py +0 -0
  541. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/testing/test_scenario_and_stubs.py +0 -0
  542. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/etl/testing/test_spark_helpers.py +0 -0
  543. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/prometheus/__init__.py +0 -0
  544. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/prometheus/test_adapter.py +0 -0
  545. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/prometheus/test_middleware.py +0 -0
  546. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/__init__.py +0 -0
  547. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_autocrud.py +0 -0
  548. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_fastapi_auto_logger.py +0 -0
  549. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_middleware.py +0 -0
  550. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
  551. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_response.py +0 -0
  552. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_rest_adapter.py +0 -0
  553. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_rest_compiler.py +0 -0
  554. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_rest_model.py +0 -0
  555. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/rest/test_router_runtime.py +0 -0
  556. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/testing/__init__.py +0 -0
  557. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/testing/test_golden.py +0 -0
  558. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/testing/test_http_harness.py +0 -0
  559. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/testing/test_in_memory.py +0 -0
  560. {loom_kernel-0.3.0 → loom_kernel-0.4.0}/tests/unit/testing/test_runner.py +0 -0
@@ -99,23 +99,28 @@ jobs:
99
99
  git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
100
100
 
101
101
  BRANCH="docs/release-v${VERSION}"
102
- git checkout -b "${BRANCH}"
102
+ git checkout -B "${BRANCH}"
103
103
 
104
104
  if [ -f CHANGELOG_RELEASE.md ]; then
105
- cat CHANGELOG_RELEASE.md CHANGELOG.md > CHANGELOG_MERGED.md
106
- mv CHANGELOG_MERGED.md CHANGELOG.md
105
+ HEADER=$(head -1 CHANGELOG_RELEASE.md)
106
+ if ! grep -qF "${HEADER}" CHANGELOG.md; then
107
+ cat CHANGELOG_RELEASE.md CHANGELOG.md > CHANGELOG_MERGED.md
108
+ mv CHANGELOG_MERGED.md CHANGELOG.md
109
+ fi
107
110
  fi
108
111
 
109
112
  git add pyproject.toml CHANGELOG.md
110
113
  git diff --staged --quiet && exit 0
111
114
  git commit -m "chore(release): bump version to ${VERSION}"
112
- git push origin "${BRANCH}"
113
-
114
- gh pr create \
115
- --title "chore(release): bump version to ${VERSION}" \
116
- --body "Automated version bump and changelog update after release v${VERSION}." \
117
- --base master \
118
- --head "${BRANCH}"
115
+ git push origin "${BRANCH}" --force
116
+
117
+ if ! gh pr list --head "${BRANCH}" --state open --json number --jq '.[0].number' | grep -qE '^[0-9]+$'; then
118
+ gh pr create \
119
+ --title "chore(release): bump version to ${VERSION}" \
120
+ --body "Automated version bump and changelog update after release v${VERSION}." \
121
+ --base master \
122
+ --head "${BRANCH}"
123
+ fi
119
124
 
120
125
  gh pr merge "${BRANCH}" --squash --auto --delete-branch
121
126
 
@@ -19,6 +19,7 @@ htmlcov/
19
19
  docs/__pycache__/
20
20
  .claude/
21
21
  .claude.md
22
+ CLAUDE.md
22
23
  AGENTS.md
23
24
 
24
25
  # Internal discussion docs (not part of distributable source)
@@ -13,3 +13,9 @@ python:
13
13
  - requirements: docs/requirements.txt
14
14
  - method: pip
15
15
  path: .
16
+ extra_requirements:
17
+ - rest
18
+ - sqlalchemy
19
+ - cache
20
+ - config
21
+ - prometheus
@@ -1,61 +1,18 @@
1
- # 🚀 Release 0.3.0 ([#14](https://github.com/the-reacher-data/loom-py/pull/14)) ([`ef414c5`](https://github.com/the-reacher-data/loom-py/commit/ef414c5bfd303296af450840318dfbe9d301e5d1))
1
+ # 🚀 Release 0.4.0 ([#18](https://github.com/the-reacher-data/loom-py/pull/18)) ([`09e5aa3`](https://github.com/the-reacher-data/loom-py/commit/09e5aa340f88e0488daca2bf10320aad7aebbe1d))
2
2
 
3
3
 
4
4
  ## ✨ Features
5
- ### config
6
- - **config:** add cloud URI support and pluggable resolver extension point<br>
7
- > Add fsspec as a hard dependency of loom[config]
8
- > load_config() now accepts s3://, gs://, abfss://, r2:// URIs via fsspec
9
- > Add ConfigResolver protocol for pluggable ${prefix:key} resolution at
10
- > parse time (enables SSM, Key Vault, etc. without baking secrets into images)
11
- > Resolver registration is idempotent; resolvers are evaluated at job startup
12
- > so secret rotation takes effect on the next run
13
- > Migrate loom.etl.runner.config_loader to use core load_config, removing
14
- > the parallel OmegaConf implementation
15
- > ETL _load_yaml inherits cloud URI and resolver support transparently
16
-
17
-
18
5
  ### etl
19
- - **etl:** add FileLocator with explicit alias API for file routes<br>
20
- > Introduces `FileLocator` protocol and `MappingFileLocator` so that
21
- > `FromFile.alias("name")` / `IntoFile.alias("name")` specs resolve at
22
- > runtime through `storage.files` config rather than hard-coded URIs.
23
- > `FileLocation` / `FileLocator` / `MappingFileLocator` in `storage/_file_locator.py`
24
- > `StorageConfig.to_file_locator()` returns `MappingFileLocator | None`
25
- > (None when `files` is empty — no conditional needed at call sites)
26
- > `FromFile.alias()` / `IntoFile.alias()` classmethods set `is_alias=True`
27
- > on the emitted spec
28
- > `is_alias: bool` added to `FileSourceSpec` and `FileSpec`
29
- > Polars and Spark backends resolve aliases via injected `file_locator`
30
- > Both providers wired: `file_locator = config.to_file_locator()`
31
- > Full test coverage across io, storage, and backend layers
6
+ - **etl:** add IntoHistory builder and SCD Type 2 domain contracts
32
7
 
33
8
 
34
9
 
35
- ## 🐛 Fixes
36
- ### observability
37
- - **observability:** honor missing table policy for record store writers
38
10
 
39
11
 
40
- ## 📖 Documentation
41
- ### etl
42
- - **etl:** keep only user guide and drop refactor docs
43
- - **etl:** expand ETL documentation and update directory table<br>
44
- > Add dummy-loom-etl companion repo link in README and etl guide
45
- > Expand README subpaths table with loom.etl and loom.core.config entries
46
- > Add FileLocator/alias API, cloud config URI, and ConfigResolver sections to etl guide
47
- > Add loom.etl.backends (polars + spark) to etl.rst API reference
48
- > Add loom.core.config to core.rst API reference
49
12
 
50
13
 
51
14
 
52
15
 
53
- ## ♻️ Refactor
54
- ### stepsql
55
- - **stepsql:** delegate SQL execution to backend readers
56
-
57
-
58
-
59
16
 
60
17
 
61
18
  # 🚀 Release 0.3.0 ([#14](https://github.com/the-reacher-data/loom-py/pull/14)) ([`ef414c5`](https://github.com/the-reacher-data/loom-py/commit/ef414c5bfd303296af450840318dfbe9d301e5d1))
@@ -118,8 +75,6 @@
118
75
 
119
76
 
120
77
 
121
-
122
-
123
78
  # 🚀 Release 0.2.1 ([#12](https://github.com/the-reacher-data/loom-py/pull/12)) ([`87f7d1f`](https://github.com/the-reacher-data/loom-py/commit/87f7d1f1eb1ccde71d0aca1c5584b83317e30707))
124
79
 
125
80
  ## ✨ Features
@@ -0,0 +1,15 @@
1
+ # 🚀 Release 0.4.0 ([#18](https://github.com/the-reacher-data/loom-py/pull/18)) ([`09e5aa3`](https://github.com/the-reacher-data/loom-py/commit/09e5aa340f88e0488daca2bf10320aad7aebbe1d))
2
+
3
+
4
+ ## ✨ Features
5
+ ### etl
6
+ - **etl:** add IntoHistory builder and SCD Type 2 domain contracts
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loom-kernel
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -78,7 +78,8 @@ Framework-agnostic Python toolkit to build backend applications with:
78
78
  - repositories decoupled from infrastructure
79
79
  - REST/FastAPI adapters with OpenAPI generation
80
80
  - background jobs and Celery workers, first-class
81
- - testing utilities for business workflows
81
+ - **declarative ETL** — compile-time-validated pipelines for Polars and Spark
82
+ - testing utilities for business workflows and ETL steps
82
83
 
83
84
  ## Purpose
84
85
 
@@ -452,6 +453,66 @@ For deeper references, review the integration examples under
452
453
  For a runnable full-stack sample with all patterns combined, check the companion repository
453
454
  [`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
454
455
 
456
+ ## ETL quick start
457
+
458
+ Install a backend:
459
+
460
+ ```bash
461
+ pip install "loom-kernel[etl-polars]"
462
+ # or
463
+ pip install "loom-kernel[etl-spark]"
464
+ ```
465
+
466
+ Declare a pipeline — sources, targets, and transformation logic are explicit and compile-time validated:
467
+
468
+ ```python
469
+ from datetime import date
470
+ import polars as pl
471
+ from loom.etl import ETLParams, ETLStep, ETLProcess, ETLPipeline, ETLRunner, FromTable, IntoTable
472
+
473
+ class DailyParams(ETLParams):
474
+ run_date: date
475
+
476
+ class CleanOrders(ETLStep[DailyParams]):
477
+ orders = FromTable("raw.orders").columns("id", "amount", "run_date")
478
+ target = IntoTable("staging.orders").replace()
479
+
480
+ def execute(self, params: DailyParams, *, orders: pl.LazyFrame) -> pl.LazyFrame:
481
+ return orders.filter(pl.col("amount") > 0)
482
+
483
+ class DailyProcess(ETLProcess[DailyParams]):
484
+ steps = [CleanOrders]
485
+
486
+ class DailyPipeline(ETLPipeline[DailyParams]):
487
+ processes = [DailyProcess]
488
+
489
+ runner = ETLRunner.from_yaml("config/etl.yaml")
490
+ runner.run(DailyPipeline, DailyParams(run_date=date.today()))
491
+ ```
492
+
493
+ Write modes — `replace`, `append`, `replace_partition`, `replace_partitions`, `replace_where`, `upsert` — are declared on the target, validated at compile time. Partition predicates use the `params` proxy so no values are hard-coded:
494
+
495
+ ```python
496
+ from loom.etl import params
497
+
498
+ target = IntoTable("staging.orders").replace_partition(
499
+ year=params.run_date.year,
500
+ month=params.run_date.month,
501
+ )
502
+ ```
503
+
504
+ File aliases decouple paths from pipelines — declare once in YAML, reference by name:
505
+
506
+ ```python
507
+ events = FromFile.alias("events_raw", format=Format.CSV)
508
+ target = IntoFile.alias("exports_daily", format=Format.PARQUET)
509
+ ```
510
+
511
+ For a full Polars + Spark + Delta Lake example see [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl).
512
+ For the complete API reference and write-mode guide see the [ETL docs](https://loom-py.readthedocs.io/en/latest/guides/etl.html).
513
+
514
+ ---
515
+
455
516
  ## Performance
456
517
 
457
518
  `loom-kernel` adds zero measurable overhead at the concurrency levels typical of
@@ -20,7 +20,8 @@ Framework-agnostic Python toolkit to build backend applications with:
20
20
  - repositories decoupled from infrastructure
21
21
  - REST/FastAPI adapters with OpenAPI generation
22
22
  - background jobs and Celery workers, first-class
23
- - testing utilities for business workflows
23
+ - **declarative ETL** — compile-time-validated pipelines for Polars and Spark
24
+ - testing utilities for business workflows and ETL steps
24
25
 
25
26
  ## Purpose
26
27
 
@@ -394,6 +395,66 @@ For deeper references, review the integration examples under
394
395
  For a runnable full-stack sample with all patterns combined, check the companion repository
395
396
  [`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
396
397
 
398
+ ## ETL quick start
399
+
400
+ Install a backend:
401
+
402
+ ```bash
403
+ pip install "loom-kernel[etl-polars]"
404
+ # or
405
+ pip install "loom-kernel[etl-spark]"
406
+ ```
407
+
408
+ Declare a pipeline — sources, targets, and transformation logic are explicit and compile-time validated:
409
+
410
+ ```python
411
+ from datetime import date
412
+ import polars as pl
413
+ from loom.etl import ETLParams, ETLStep, ETLProcess, ETLPipeline, ETLRunner, FromTable, IntoTable
414
+
415
+ class DailyParams(ETLParams):
416
+ run_date: date
417
+
418
+ class CleanOrders(ETLStep[DailyParams]):
419
+ orders = FromTable("raw.orders").columns("id", "amount", "run_date")
420
+ target = IntoTable("staging.orders").replace()
421
+
422
+ def execute(self, params: DailyParams, *, orders: pl.LazyFrame) -> pl.LazyFrame:
423
+ return orders.filter(pl.col("amount") > 0)
424
+
425
+ class DailyProcess(ETLProcess[DailyParams]):
426
+ steps = [CleanOrders]
427
+
428
+ class DailyPipeline(ETLPipeline[DailyParams]):
429
+ processes = [DailyProcess]
430
+
431
+ runner = ETLRunner.from_yaml("config/etl.yaml")
432
+ runner.run(DailyPipeline, DailyParams(run_date=date.today()))
433
+ ```
434
+
435
+ Write modes — `replace`, `append`, `replace_partition`, `replace_partitions`, `replace_where`, `upsert` — are declared on the target, validated at compile time. Partition predicates use the `params` proxy so no values are hard-coded:
436
+
437
+ ```python
438
+ from loom.etl import params
439
+
440
+ target = IntoTable("staging.orders").replace_partition(
441
+ year=params.run_date.year,
442
+ month=params.run_date.month,
443
+ )
444
+ ```
445
+
446
+ File aliases decouple paths from pipelines — declare once in YAML, reference by name:
447
+
448
+ ```python
449
+ events = FromFile.alias("events_raw", format=Format.CSV)
450
+ target = IntoFile.alias("exports_daily", format=Format.PARQUET)
451
+ ```
452
+
453
+ For a full Polars + Spark + Delta Lake example see [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl).
454
+ For the complete API reference and write-mode guide see the [ETL docs](https://loom-py.readthedocs.io/en/latest/guides/etl.html).
455
+
456
+ ---
457
+
397
458
  ## Performance
398
459
 
399
460
  `loom-kernel` adds zero measurable overhead at the concurrency levels typical of
@@ -29,7 +29,7 @@ extensions = [
29
29
  ]
30
30
 
31
31
  templates_path = ["_templates"]
32
- exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
32
+ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "guides", "architecture", "examples-repo"]
33
33
 
34
34
  html_theme = "furo"
35
35
  html_static_path = ["_static"]
@@ -0,0 +1,29 @@
1
+ # ETL Examples
2
+
3
+ The companion repository [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl)
4
+ contains runnable end-to-end examples of `loom.etl` with both Polars and Spark
5
+ backends.
6
+
7
+ ## What it covers
8
+
9
+ - Polars and Spark pipeline declarations
10
+ - Delta Lake read/write modes (`replace`, `upsert`, `replace_partitions`)
11
+ - Cloud storage configuration (S3, GCS, Azure) via `fsspec`
12
+ - File aliases with `FromFile.alias` / `IntoFile.alias`
13
+ - Observability and run sinks
14
+ - Integration tests with `PolarsStepRunner` and `SparkTestSession`
15
+
16
+ ## Quick start
17
+
18
+ ```bash
19
+ git clone https://github.com/the-reacher-data/dummy-loom-etl
20
+ cd dummy-loom-etl
21
+ make test # run Polars and Spark test suites
22
+ make run # run the sample pipeline locally
23
+ ```
24
+
25
+ ## Next steps
26
+
27
+ - [ETL pipelines guide](pipelines.md)
28
+ - [ETL testing guide](testing.md)
29
+ - [API reference](../reference/api/etl)
@@ -0,0 +1,65 @@
1
+ # ETL Testing
2
+
3
+ `loom.etl.testing` provides in-memory harnesses for testing `ETLStep`
4
+ subclasses without spinning up a real catalog or writing to Delta Lake.
5
+
6
+ ## Test a single step with Polars
7
+
8
+ `PolarsStepRunner` seeds source tables as plain Python tuples, runs one step,
9
+ and returns a `StepResult` for assertions.
10
+
11
+ ```python
12
+ from loom.etl.testing import PolarsStepRunner
13
+
14
+ def test_clean_orders():
15
+ runner = PolarsStepRunner()
16
+ runner.seed("raw.orders", [(1, 10.0), (2, -5.0)], ["id", "amount"])
17
+ result = runner.run(CleanOrdersStep, NoParams())
18
+
19
+ result.assert_count(1)
20
+ result.assert_schema({"id": "Int64", "amount": "Float64"})
21
+ ```
22
+
23
+ `StepResult` methods: `assert_schema`, `assert_count`, `assert_not_empty`,
24
+ `show`, `to_polars`.
25
+
26
+ ## Reusable seed datasets with `ETLScenario`
27
+
28
+ `ETLScenario` stores seed data as plain tuples so the same dataset can be used
29
+ with any backend runner.
30
+
31
+ ```python
32
+ from loom.etl.testing import ETLScenario
33
+
34
+ ORDERS = (
35
+ ETLScenario()
36
+ .with_table("raw.orders", [(1, 10.0), (2, 20.0)], ["id", "amount"])
37
+ )
38
+
39
+ def test_double_amount(loom_polars_runner):
40
+ ORDERS.apply(loom_polars_runner)
41
+ result = loom_polars_runner.run(DoubleAmountStep, NoParams())
42
+ result.assert_count(2)
43
+ ```
44
+
45
+ Pytest fixtures auto-registered: `loom_polars_runner`, `loom_spark_runner`.
46
+
47
+ ## Spark integration tests
48
+
49
+ Use `SparkTestSession` for a real PySpark + Delta session:
50
+
51
+ ```python
52
+ from loom.etl.testing.spark import SparkTestSession
53
+
54
+ with SparkTestSession.start() as spark:
55
+ runner = SparkStepRunner(spark)
56
+ runner.seed("raw.orders", [(1, 10.0)], ["id", "amount"])
57
+ result = runner.run(CleanOrdersStep, NoParams())
58
+ result.assert_count(1)
59
+ ```
60
+
61
+ ## Compile-time stubs
62
+
63
+ - `StubCatalog` — in-memory catalog.
64
+ - `StubSourceReader` / `StubTargetWriter` — in-memory I/O.
65
+ - `StubRunObserver` — records pipeline lifecycle events.
@@ -0,0 +1,136 @@
1
+ # ETL Quickstart
2
+
3
+ `loom.etl` is a declarative ETL subsystem with compile-time validation,
4
+ backend-agnostic declarations, and a single runtime entrypoint (`ETLRunner`).
5
+
6
+ ## Install
7
+
8
+ Choose one backend:
9
+
10
+ ```bash
11
+ pip install "loom-kernel[etl-polars]"
12
+ # or
13
+ pip install "loom-kernel[etl-spark]"
14
+ ```
15
+
16
+ ## Minimal pipeline
17
+
18
+ ```python
19
+ from datetime import date
20
+
21
+ import polars as pl
22
+ from loom.etl import (
23
+ ETLParams,
24
+ ETLStep,
25
+ ETLProcess,
26
+ ETLPipeline,
27
+ ETLRunner,
28
+ FromTable,
29
+ IntoTable,
30
+ )
31
+
32
+
33
+ class DailyParams(ETLParams):
34
+ run_date: date
35
+
36
+
37
+ class CleanOrders(ETLStep[DailyParams]):
38
+ orders = FromTable("raw.orders").columns("id", "amount", "run_date")
39
+ target = IntoTable("staging.orders").replace()
40
+
41
+ def execute(self, params: DailyParams, *, orders: pl.LazyFrame) -> pl.LazyFrame:
42
+ return orders.filter(pl.col("amount") > 0)
43
+
44
+
45
+ class DailyProcess(ETLProcess[DailyParams]):
46
+ steps = [CleanOrders]
47
+
48
+
49
+ class DailyPipeline(ETLPipeline[DailyParams]):
50
+ processes = [DailyProcess]
51
+
52
+
53
+ runner = ETLRunner.from_dict(
54
+ storage={
55
+ "engine": "polars",
56
+ "defaults": {"table_path": {"uri": "/var/lib/loom/lake"}},
57
+ }
58
+ )
59
+ runner.run(DailyPipeline, DailyParams(run_date=date(2026, 3, 30)))
60
+ ```
61
+
62
+ ## Basic write modes
63
+
64
+ Every `IntoTable` target declares exactly one write mode by chaining a method.
65
+
66
+ | Mode | What it does | Example |
67
+ |------|--------------|---------|
68
+ | `append` | Add rows to the table | `IntoTable("staging.orders").append()` |
69
+ | `replace` | Full overwrite | `IntoTable("staging.orders").replace()` |
70
+ | `replace_partitions` | Overwrite only partitions present in the batch | `IntoTable("staging.orders").replace_partitions("year", "month")` |
71
+ | `replace_partition` | Overwrite a single known partition | `IntoTable("staging.orders").replace_partition(year=params.run_date.year)` |
72
+ | `replace_where` | Overwrite rows matching a predicate | `IntoTable("staging.orders").replace_where(col("date") == params.run_date)` |
73
+ | `upsert` | Merge on key columns | `IntoTable("staging.orders").upsert(keys=("order_id",))` |
74
+
75
+ See the [ETL pipelines guide](../etl/pipelines.md) for the full write-mode reference.
76
+
77
+ ## YAML config
78
+
79
+ ```yaml
80
+ storage:
81
+ engine: polars
82
+ defaults:
83
+ table_path:
84
+ uri: s3://my-lake
85
+ storage_options:
86
+ AWS_REGION: ${oc.env:AWS_REGION}
87
+ AWS_ACCESS_KEY_ID: ${oc.env:AWS_ACCESS_KEY_ID}
88
+ AWS_SECRET_ACCESS_KEY: ${oc.env:AWS_SECRET_ACCESS_KEY}
89
+
90
+ tmp_root: /var/lib/loom/lake/_tmp
91
+
92
+ observability:
93
+ log: true
94
+ slow_step_threshold_ms: 30000
95
+ run_sink:
96
+ root: /var/lib/loom/lake/_runs
97
+ ```
98
+
99
+ ```python
100
+ from loom.etl import ETLRunner
101
+
102
+ runner = ETLRunner.from_yaml("config/etl.yaml")
103
+ ```
104
+
105
+ ## File aliases
106
+
107
+ Hard-coding file paths couples logic to infrastructure. Use aliases instead:
108
+
109
+ ```yaml
110
+ storage:
111
+ engine: polars
112
+ files:
113
+ - name: events_raw
114
+ path:
115
+ uri: s3://raw-bucket/events/
116
+ storage_options:
117
+ AWS_REGION: eu-west-1
118
+ ```
119
+
120
+ ```python
121
+ from loom.etl import ETLStep, FromFile, IntoFile, Format
122
+
123
+ class LoadEvents(ETLStep[DailyParams]):
124
+ events = FromFile.alias("events_raw", format=Format.CSV)
125
+ target = IntoFile.alias("exports_daily", format=Format.PARQUET)
126
+
127
+ def execute(self, params: DailyParams, *, events: pl.LazyFrame) -> pl.LazyFrame:
128
+ return events
129
+ ```
130
+
131
+ ## Next steps
132
+
133
+ - [ETL pipelines guide](../etl/pipelines.md) — full write modes, Spark runtime, cloud config, and pluggable resolvers
134
+ - [ETL testing guide](../etl/testing.md) — in-memory runners, scenarios, and stubs
135
+ - [ETL examples](../etl/examples.md) — companion repository with runnable Polars and Spark pipelines
136
+ - [API reference](../reference/api/etl)