loom-kernel 2.21.0__tar.gz → 2.22.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 (689) hide show
  1. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/PKG-INFO +1 -1
  2. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/__init__.py +2 -0
  3. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_historify/_common.py +11 -0
  4. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_historify/_log.py +26 -1
  5. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_historify/_ops.py +22 -1
  6. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_historify/_transform.py +22 -3
  7. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_write_policy.py +52 -42
  8. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_historify.py +37 -12
  9. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_writer.py +3 -36
  10. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/spark/_historify.py +38 -11
  11. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/spark/_writer.py +3 -37
  12. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_validators_step.py +40 -0
  13. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/__init__.py +2 -0
  14. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/__init__.py +3 -0
  15. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_history/__init__.py +2 -0
  16. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_history/_builder.py +75 -0
  17. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_history/_errors.py +38 -8
  18. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_history/_spec.py +6 -0
  19. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/.gitignore +0 -0
  20. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/CHANGELOG.md +0 -0
  21. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/LICENSE +0 -0
  22. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/README.md +0 -0
  23. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/pyproject.toml +0 -0
  24. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/__init__.py +0 -0
  25. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/__init__.py +0 -0
  26. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/_concurrency.py +0 -0
  27. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/_filters.py +0 -0
  28. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/_paths.py +0 -0
  29. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/_roles.py +0 -0
  30. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/_startup.py +0 -0
  31. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/_transport.py +0 -0
  32. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/_usecase.py +0 -0
  33. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/a2a/__init__.py +0 -0
  34. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/a2a/_binding.py +0 -0
  35. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/a2a/_handlers.py +0 -0
  36. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/a2a/_rpc.py +0 -0
  37. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/a2a/card.py +0 -0
  38. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/a2a/events.py +0 -0
  39. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/a2a/server.py +0 -0
  40. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/abc.py +0 -0
  41. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/bootstrap.py +0 -0
  42. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/__init__.py +0 -0
  43. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/_compiler.py +0 -0
  44. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/_fingerprint.py +0 -0
  45. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/_plan.py +0 -0
  46. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
  47. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
  48. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
  49. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
  50. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
  51. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
  52. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
  53. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
  54. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_output.py +0 -0
  55. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/compiler/phases/_state.py +0 -0
  56. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/config.py +0 -0
  57. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/declarative/__init__.py +0 -0
  58. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/declarative/_envelope.py +0 -0
  59. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/declarative/_schema.py +0 -0
  60. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/declarative/_v1.py +0 -0
  61. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
  62. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/describe.py +0 -0
  63. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/__init__.py +0 -0
  64. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
  65. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
  66. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
  67. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
  68. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
  69. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
  70. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
  71. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
  72. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
  73. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
  74. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
  75. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
  76. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
  77. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
  78. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
  79. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
  80. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
  81. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
  82. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
  83. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
  84. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
  85. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
  86. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
  87. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
  88. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
  89. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
  90. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
  91. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
  92. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
  93. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
  94. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
  95. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/errors.py +0 -0
  96. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/etl/__init__.py +0 -0
  97. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/etl/_batch.py +0 -0
  98. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/etl/_columns.py +0 -0
  99. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/etl/_frames.py +0 -0
  100. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/etl/_ledger.py +0 -0
  101. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/etl/_runner.py +0 -0
  102. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/etl/_validation.py +0 -0
  103. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/fastapi/__init__.py +0 -0
  104. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/fastapi/endpoints.py +0 -0
  105. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/fastapi/response.py +0 -0
  106. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/fastapi/streaming.py +0 -0
  107. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/inference.py +0 -0
  108. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/pricing.py +0 -0
  109. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/registry.py +0 -0
  110. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/remote_auth.py +0 -0
  111. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/__init__.py +0 -0
  112. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_bounded.py +0 -0
  113. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_chain.py +0 -0
  114. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_conversation.py +0 -0
  115. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_grants.py +0 -0
  116. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_handle.py +0 -0
  117. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_health.py +0 -0
  118. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_hooks.py +0 -0
  119. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
  120. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_limits.py +0 -0
  121. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/runtime/_mcp.py +0 -0
  122. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/validate/__init__.py +0 -0
  123. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/ai/validate/__main__.py +0 -0
  124. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/celery/__init__.py +0 -0
  125. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/celery/auto.py +0 -0
  126. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/celery/bootstrap.py +0 -0
  127. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/celery/config.py +0 -0
  128. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/celery/constants.py +0 -0
  129. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/celery/runner.py +0 -0
  130. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/celery/service.py +0 -0
  131. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/cli/__init__.py +0 -0
  132. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/cli/app.py +0 -0
  133. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/cli/schema.py +0 -0
  134. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/async_bridge.py +0 -0
  135. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/authz/__init__.py +0 -0
  136. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/authz/_decide.py +0 -0
  137. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/authz/_grants.py +0 -0
  138. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/authz/_roles.py +0 -0
  139. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/authz/_scope.py +0 -0
  140. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/authz/elevation.py +0 -0
  141. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/authz/product.py +0 -0
  142. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/backend/__init__.py +0 -0
  143. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/backend/core_model.py +0 -0
  144. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/backend/protocol.py +0 -0
  145. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/backend/scoped_ddl.py +0 -0
  146. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/backend/sqlalchemy.py +0 -0
  147. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/bootstrap/__init__.py +0 -0
  148. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
  149. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/bootstrap/kernel.py +0 -0
  150. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/__init__.py +0 -0
  151. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/_batching.py +0 -0
  152. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/_single_flight.py +0 -0
  153. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/abc/__init__.py +0 -0
  154. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/abc/backend.py +0 -0
  155. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/abc/config.py +0 -0
  156. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/abc/dependency.py +0 -0
  157. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/calls.py +0 -0
  158. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/codec.py +0 -0
  159. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/decorators.py +0 -0
  160. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/dependency.py +0 -0
  161. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/errors.py +0 -0
  162. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/gateway.py +0 -0
  163. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/keys.py +0 -0
  164. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/memory.py +0 -0
  165. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/repository.py +0 -0
  166. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/result_codec.py +0 -0
  167. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/serializer.py +0 -0
  168. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/cache/wiring.py +0 -0
  169. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/command/__init__.py +0 -0
  170. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/command/adapter.py +0 -0
  171. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/command/base.py +0 -0
  172. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/command/field.py +0 -0
  173. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/command/introspection.py +0 -0
  174. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/compiler.py +0 -0
  175. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/__init__.py +0 -0
  176. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/_boto3.py +0 -0
  177. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/_includes.py +0 -0
  178. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/_resolver_utils.py +0 -0
  179. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/binder.py +0 -0
  180. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/configurable.py +0 -0
  181. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/context.py +0 -0
  182. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/errors.py +0 -0
  183. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/keys.py +0 -0
  184. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/loader.py +0 -0
  185. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/model.py +0 -0
  186. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/observability.py +0 -0
  187. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/resolver.py +0 -0
  188. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/secrets.py +0 -0
  189. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/config/ssm.py +0 -0
  190. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/contracts/__init__.py +0 -0
  191. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/contracts/manifest.py +0 -0
  192. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/di/__init__.py +0 -0
  193. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/di/container.py +0 -0
  194. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/di/scope.py +0 -0
  195. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/discovery/__init__.py +0 -0
  196. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/discovery/_utils.py +0 -0
  197. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/discovery/base.py +0 -0
  198. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/discovery/interfaces.py +0 -0
  199. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/discovery/manifest.py +0 -0
  200. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/discovery/modules.py +0 -0
  201. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/engine/__init__.py +0 -0
  202. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/engine/compilable.py +0 -0
  203. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/engine/compiler.py +0 -0
  204. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/engine/events.py +0 -0
  205. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/engine/executor.py +0 -0
  206. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/engine/metrics.py +0 -0
  207. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/engine/plan.py +0 -0
  208. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/engine/post_commit.py +0 -0
  209. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/errors/__init__.py +0 -0
  210. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/errors/codes.py +0 -0
  211. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/errors/errors.py +0 -0
  212. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/expr/__init__.py +0 -0
  213. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/expr/eval.py +0 -0
  214. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/expr/nodes.py +0 -0
  215. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/expr/refs.py +0 -0
  216. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/identity/__init__.py +0 -0
  217. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/identity/context.py +0 -0
  218. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/identity/identity.py +0 -0
  219. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/identity/issuer.py +0 -0
  220. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/identity/wire.py +0 -0
  221. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/introspection/__init__.py +0 -0
  222. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/introspection/base.py +0 -0
  223. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/introspection/describe.py +0 -0
  224. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/job/__init__.py +0 -0
  225. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/job/callback.py +0 -0
  226. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/job/context.py +0 -0
  227. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/job/handle.py +0 -0
  228. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/job/job.py +0 -0
  229. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/job/service.py +0 -0
  230. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/locator.py +0 -0
  231. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/logger/__init__.py +0 -0
  232. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/logger/abc.py +0 -0
  233. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/logger/config.py +0 -0
  234. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/logger/registry.py +0 -0
  235. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/logger/structlogger.py +0 -0
  236. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/__init__.py +0 -0
  237. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/_json_schema.py +0 -0
  238. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/_loom_type.py +0 -0
  239. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/base.py +0 -0
  240. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/convert.py +0 -0
  241. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/enums.py +0 -0
  242. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/field.py +0 -0
  243. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/introspection.py +0 -0
  244. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/partition.py +0 -0
  245. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/privilege.py +0 -0
  246. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/projection.py +0 -0
  247. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/relation.py +0 -0
  248. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/scoped.py +0 -0
  249. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/struct.py +0 -0
  250. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/timestamped.py +0 -0
  251. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/types.py +0 -0
  252. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/model/types_postgres.py +0 -0
  253. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/__init__.py +0 -0
  254. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/config.py +0 -0
  255. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/event.py +0 -0
  256. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/observer/__init__.py +0 -0
  257. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/observer/noop.py +0 -0
  258. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/observer/otel.py +0 -0
  259. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/observer/structlog.py +0 -0
  260. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/otel_ids.py +0 -0
  261. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/protocol.py +0 -0
  262. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/runtime.py +0 -0
  263. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/span.py +0 -0
  264. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/observability/topology.py +0 -0
  265. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/persistence/__init__.py +0 -0
  266. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/persistence/abc.py +0 -0
  267. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/persistence/none.py +0 -0
  268. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/persistence/registry.py +0 -0
  269. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/plugins/__init__.py +0 -0
  270. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/plugins/entrypoints.py +0 -0
  271. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/plugins/optional.py +0 -0
  272. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/projection/__init__.py +0 -0
  273. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/projection/loaders.py +0 -0
  274. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/projection/runtime.py +0 -0
  275. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/__init__.py +0 -0
  276. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/abc/__init__.py +0 -0
  277. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/abc/cursor.py +0 -0
  278. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/abc/errors.py +0 -0
  279. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/abc/query.py +0 -0
  280. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
  281. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  282. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/abc/repository.py +0 -0
  283. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/abc/session_scope.py +0 -0
  284. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
  285. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/dynamodb/backend.py +0 -0
  286. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
  287. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
  288. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
  289. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mongo/__init__.py +0 -0
  290. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mongo/backend.py +0 -0
  291. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mongo/ids.py +0 -0
  292. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
  293. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mongo/registry.py +0 -0
  294. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mongo/repository.py +0 -0
  295. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mongo/uow.py +0 -0
  296. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mongo/values.py +0 -0
  297. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/mutation.py +0 -0
  298. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/registration.py +0 -0
  299. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/registry.py +0 -0
  300. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  301. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/backend.py +0 -0
  302. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  303. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  304. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
  305. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
  306. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
  307. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
  308. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +0 -0
  309. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
  310. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  311. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  312. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  313. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  314. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  315. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  316. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  317. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
  318. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  319. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  320. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  321. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  322. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  323. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +0 -0
  324. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
  325. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
  326. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
  327. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
  328. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
  329. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
  330. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -0
  331. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +0 -0
  332. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
  333. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
  334. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
  335. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
  336. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +0 -0
  337. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
  338. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
  339. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  340. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  341. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/response/__init__.py +0 -0
  342. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/response/base.py +0 -0
  343. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/routing/__init__.py +0 -0
  344. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/routing/ref.py +0 -0
  345. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/routing/resolver.py +0 -0
  346. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/runner.py +0 -0
  347. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/schema/__init__.py +0 -0
  348. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/schema/schema_mode.py +0 -0
  349. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/schema_names.py +0 -0
  350. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/__init__.py +0 -0
  351. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/abc/__init__.py +0 -0
  352. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/abc/contracts.py +0 -0
  353. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/abc/errors.py +0 -0
  354. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/caller_bound.py +0 -0
  355. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
  356. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
  357. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
  358. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
  359. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/config.py +0 -0
  360. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/roles.py +0 -0
  361. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/sql/service.py +0 -0
  362. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/symbols.py +0 -0
  363. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/tracing/__init__.py +0 -0
  364. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/tracing/context.py +0 -0
  365. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/transaction.py +0 -0
  366. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/transport/__init__.py +0 -0
  367. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/transport/adapter.py +0 -0
  368. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/uow/__init__.py +0 -0
  369. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/uow/abc.py +0 -0
  370. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/uow/context.py +0 -0
  371. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/__init__.py +0 -0
  372. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/_predicates.py +0 -0
  373. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/agent_markers.py +0 -0
  374. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/compute.py +0 -0
  375. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/constants.py +0 -0
  376. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/factory.py +0 -0
  377. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/field_ref.py +0 -0
  378. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/invoker.py +0 -0
  379. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/keys.py +0 -0
  380. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/markers.py +0 -0
  381. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/mcp_markers.py +0 -0
  382. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/outcome.py +0 -0
  383. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/registry.py +0 -0
  384. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/rule.py +0 -0
  385. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/core/use_case/use_case.py +0 -0
  386. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/_uri.py +0 -0
  387. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/__init__.py +0 -0
  388. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_format_registry.py +0 -0
  389. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
  390. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
  391. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_merge.py +0 -0
  392. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_path_template.py +0 -0
  393. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_predicate.py +0 -0
  394. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  395. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  396. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  397. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/__init__.py +0 -0
  398. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  399. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  400. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_frame.py +0 -0
  401. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  402. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_reader.py +0 -0
  403. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  404. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  405. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
  406. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/polars/provider.py +0 -0
  407. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  408. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  409. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  410. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  411. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  412. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/backends/spark/provider.py +0 -0
  413. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/checkpoint/__init__.py +0 -0
  414. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
  415. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  416. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
  417. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/checkpoint/_options.py +0 -0
  418. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  419. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  420. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/checkpoint/_store.py +0 -0
  421. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/__init__.py +0 -0
  422. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_binding.py +0 -0
  423. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_compiler.py +0 -0
  424. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_errors.py +0 -0
  425. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_filter.py +0 -0
  426. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_plan.py +0 -0
  427. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_validators.py +0 -0
  428. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_validators_agents.py +0 -0
  429. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_validators_config.py +0 -0
  430. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  431. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/_format.py +0 -0
  432. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/_read_options.py +0 -0
  433. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/_utils.py +0 -0
  434. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/_with_agent.py +0 -0
  435. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/_write_options.py +0 -0
  436. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  437. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  438. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  439. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  440. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
  441. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/source/__init__.py +0 -0
  442. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/source/_from.py +0 -0
  443. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
  444. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
  445. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
  446. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
  447. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/source/_specs.py +0 -0
  448. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_client.py +0 -0
  449. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_errors.py +0 -0
  450. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_file.py +0 -0
  451. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
  452. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
  453. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_into.py +0 -0
  454. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
  455. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_table.py +0 -0
  456. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  457. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/executor/__init__.py +0 -0
  458. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/executor/_agents.py +0 -0
  459. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  460. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/executor/_executor.py +0 -0
  461. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/__init__.py +0 -0
  462. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/_registry.py +0 -0
  463. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/__init__.py +0 -0
  464. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
  465. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
  466. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
  467. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
  468. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_mongo.py +0 -0
  469. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
  470. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
  471. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
  472. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/sources/_serialization.py +0 -0
  473. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/targets/__init__.py +0 -0
  474. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
  475. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/lineage/__init__.py +0 -0
  476. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/lineage/_config.py +0 -0
  477. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/lineage/_observer.py +0 -0
  478. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/lineage/_records.py +0 -0
  479. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
  480. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
  481. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
  482. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
  483. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/maintenance/__init__.py +0 -0
  484. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/maintenance/_builder.py +0 -0
  485. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/maintenance/_ops.py +0 -0
  486. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/maintenance/_protocol.py +0 -0
  487. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/maintenance/_runner.py +0 -0
  488. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/maintenance/_step.py +0 -0
  489. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
  490. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
  491. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/__init__.py +0 -0
  492. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/_generics.py +0 -0
  493. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/_params.py +0 -0
  494. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  495. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/_process.py +0 -0
  496. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/_sql.py +0 -0
  497. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/_step.py +0 -0
  498. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/_step_client.py +0 -0
  499. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  500. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runner/__init__.py +0 -0
  501. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runner/_agents.py +0 -0
  502. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runner/_providers.py +0 -0
  503. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runner/_wiring.py +0 -0
  504. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runner/config_loader.py +0 -0
  505. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runner/core.py +0 -0
  506. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runner/errors.py +0 -0
  507. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runner/filtering.py +0 -0
  508. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runtime/__init__.py +0 -0
  509. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runtime/_config_values.py +0 -0
  510. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/runtime/contracts.py +0 -0
  511. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/schema/__init__.py +0 -0
  512. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/schema/_contract.py +0 -0
  513. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/schema/_schema.py +0 -0
  514. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/storage/__init__.py +0 -0
  515. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/storage/_config.py +0 -0
  516. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/storage/_file_locator.py +0 -0
  517. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/storage/_locator.py +0 -0
  518. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/storage/routing.py +0 -0
  519. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/testing/__init__.py +0 -0
  520. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/testing/_result.py +0 -0
  521. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/testing/_runners.py +0 -0
  522. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/testing/_scenario.py +0 -0
  523. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/testing/_stubs.py +0 -0
  524. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/etl/testing/spark.py +0 -0
  525. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/__init__.py +0 -0
  526. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/_async.py +0 -0
  527. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/_config.py +0 -0
  528. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/_ctx.py +0 -0
  529. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/_flow_yaml.py +0 -0
  530. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/_meta.py +0 -0
  531. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/_placeholders.py +0 -0
  532. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/_summary.py +0 -0
  533. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/deploy/__init__.py +0 -0
  534. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/deploy/_discovery.py +0 -0
  535. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/deploy/_schedule.py +0 -0
  536. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/deploy/_yaml_etls.py +0 -0
  537. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/deploy/entrypoint.py +0 -0
  538. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/__init__.py +0 -0
  539. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_assemble.py +0 -0
  540. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_backfill.py +0 -0
  541. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
  542. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_body.py +0 -0
  543. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_common.py +0 -0
  544. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_factory.py +0 -0
  545. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_hooks.py +0 -0
  546. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_maintenance.py +0 -0
  547. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_params.py +0 -0
  548. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_run_name.py +0 -0
  549. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_runtime.py +0 -0
  550. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_signature.py +0 -0
  551. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/flow/_stages.py +0 -0
  552. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/manifest/__init__.py +0 -0
  553. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/manifest/_model.py +0 -0
  554. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/manifest/_s3.py +0 -0
  555. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/manifest/_store.py +0 -0
  556. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/notify/__init__.py +0 -0
  557. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/notify/_event.py +0 -0
  558. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/notify/_factory.py +0 -0
  559. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/notify/_format.py +0 -0
  560. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/notify/_port.py +0 -0
  561. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/notify/_slack.py +0 -0
  562. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/notify/_sns.py +0 -0
  563. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/observer/__init__.py +0 -0
  564. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/observer/_flow.py +0 -0
  565. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
  566. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/observer/_manifest.py +0 -0
  567. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prefect/observer/_task_run.py +0 -0
  568. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prometheus/__init__.py +0 -0
  569. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prometheus/_instruments.py +0 -0
  570. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prometheus/adapter.py +0 -0
  571. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prometheus/kafka.py +0 -0
  572. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prometheus/lifecycle.py +0 -0
  573. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/prometheus/middleware.py +0 -0
  574. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/py.typed +0 -0
  575. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/__init__.py +0 -0
  576. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/_body.py +0 -0
  577. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/adapter.py +0 -0
  578. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/auth/__init__.py +0 -0
  579. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/auth/abc.py +0 -0
  580. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/auth/config.py +0 -0
  581. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/auth/jwt.py +0 -0
  582. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/auth/middleware.py +0 -0
  583. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/autocrud.py +0 -0
  584. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/compiler.py +0 -0
  585. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/config.py +0 -0
  586. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/constants.py +0 -0
  587. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/cors.py +0 -0
  588. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/errors.py +0 -0
  589. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/__init__.py +0 -0
  590. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/_errors.py +0 -0
  591. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
  592. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/app.py +0 -0
  593. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/auto.py +0 -0
  594. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/health.py +0 -0
  595. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/openapi.py +0 -0
  596. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/response.py +0 -0
  597. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
  598. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/fastapi/sql.py +0 -0
  599. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/middleware.py +0 -0
  600. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/model.py +0 -0
  601. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/rest/rest_adapter.py +0 -0
  602. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/__init__.py +0 -0
  603. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/__init__.py +0 -0
  604. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
  605. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
  606. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
  607. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
  608. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
  609. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_errors.py +0 -0
  610. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_operators.py +0 -0
  611. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
  612. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
  613. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
  614. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
  615. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
  616. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
  617. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
  618. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
  619. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
  620. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
  621. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
  622. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
  623. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/bytewax/runner.py +0 -0
  624. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/compiler/__init__.py +0 -0
  625. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/compiler/_bindings.py +0 -0
  626. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/compiler/_compiler.py +0 -0
  627. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/compiler/_errors.py +0 -0
  628. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/compiler/_plan.py +0 -0
  629. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
  630. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
  631. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/core/__init__.py +0 -0
  632. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/core/_errors.py +0 -0
  633. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/core/_exceptions.py +0 -0
  634. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/core/_message.py +0 -0
  635. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/core/_tracing.py +0 -0
  636. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/core/_typing.py +0 -0
  637. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/graph/__init__.py +0 -0
  638. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/graph/_flow.py +0 -0
  639. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/__init__.py +0 -0
  640. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/_codec.py +0 -0
  641. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/_config.py +0 -0
  642. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/_errors.py +0 -0
  643. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
  644. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/_message.py +0 -0
  645. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/_record.py +0 -0
  646. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/_wire.py +0 -0
  647. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
  648. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
  649. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
  650. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
  651. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
  652. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
  653. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
  654. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
  655. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
  656. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/mongo/__init__.py +0 -0
  657. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
  658. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/mongo/_config.py +0 -0
  659. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/mongo/_event.py +0 -0
  660. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/mongo/_normalize.py +0 -0
  661. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/__init__.py +0 -0
  662. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_boundary.py +0 -0
  663. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_branches.py +0 -0
  664. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
  665. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
  666. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_decompose.py +0 -0
  667. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
  668. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
  669. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_fork.py +0 -0
  670. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_helpers.py +0 -0
  671. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_mongo.py +0 -0
  672. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_protocols.py +0 -0
  673. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_router.py +0 -0
  674. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_shape.py +0 -0
  675. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_sink.py +0 -0
  676. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_step.py +0 -0
  677. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
  678. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_table/common.py +0 -0
  679. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_table/config.py +0 -0
  680. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/_with.py +0 -0
  681. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/nodes/refs.py +0 -0
  682. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/streaming/testing.py +0 -0
  683. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/testing/__init__.py +0 -0
  684. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/testing/agents.py +0 -0
  685. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/testing/golden.py +0 -0
  686. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/testing/http_harness.py +0 -0
  687. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/testing/in_memory.py +0 -0
  688. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/testing/repository_harness.py +0 -0
  689. {loom_kernel-2.21.0 → loom_kernel-2.22.0}/src/loom/testing/runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: loom-kernel
3
- Version: 2.21.0
3
+ Version: 2.22.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Classifier: Programming Language :: Python :: 3
@@ -63,6 +63,7 @@ from loom.etl.declarative import (
63
63
  FromTable,
64
64
  FromTemp,
65
65
  HistorifyDateCollisionError,
66
+ HistorifyDeleteMarkerError,
66
67
  HistorifyInputMode,
67
68
  HistorifyKeyConflictError,
68
69
  HistorifyRepairReport,
@@ -203,6 +204,7 @@ __all__ = [
203
204
  # SCD2 errors
204
205
  "HistorifyKeyConflictError",
205
206
  "HistorifyDateCollisionError",
207
+ "HistorifyDeleteMarkerError",
206
208
  "HistorifyTemporalConflictError",
207
209
  "EmptyReplaceError",
208
210
  # intermediates
@@ -42,9 +42,20 @@ def resolve_track_cols(spec: HistorifySpec, frame_cols: list[str]) -> tuple[str,
42
42
  if spec.track is not None:
43
43
  return spec.track
44
44
  excluded = set(spec.keys) | {spec.valid_from, spec.valid_to}
45
+ if spec.delete_marker is not None:
46
+ excluded.add(spec.delete_marker)
45
47
  return tuple(c for c in frame_cols if c not in excluded)
46
48
 
47
49
 
50
+ def log_run_cols(spec: HistorifySpec) -> list[str]:
51
+ """Return the columns whose change starts a new LOG run: ``track`` plus the delete marker.
52
+
53
+ Including the marker keeps a tombstone from collapsing into the run it closes.
54
+ """
55
+ marker = [spec.delete_marker] if spec.delete_marker is not None else []
56
+ return [*(spec.track or ()), *marker]
57
+
58
+
48
59
  def prev_period_value(eff_date: Any, spec: HistorifySpec) -> Any:
49
60
  """Return one unit before eff_date (one day or one microsecond)."""
50
61
  delta = _DATE_DELTA if spec.date_type is HistoryDateType.DATE else _TS_DELTA
@@ -24,6 +24,9 @@ def apply_log(
24
24
  history is rebuilt from the union of existing events and incoming events.
25
25
  Incoming events win on same ``(entity key, effective date)`` conflicts, so
26
26
  a correction with different tracked values replaces the stored event.
27
+ With ``delete_marker`` set, every stored closure without a successor is
28
+ replayed as a tombstone so the rebuild keeps it closed. Removing the marker
29
+ later would merge those closures back into open history.
27
30
  """
28
31
  eff_col = str(spec.effective_date)
29
32
  entity_keys = list(spec.keys)
@@ -36,6 +39,12 @@ def apply_log(
36
39
  c for c in [spec.valid_to, spec.deleted_at] if c in ops.columns(existing_events)
37
40
  ]
38
41
  existing_events = ops.drop(existing_events, boundary_cols)
42
+ marker = spec.delete_marker
43
+ if marker is not None:
44
+ stored_tombstones = ops.stamp_col(
45
+ ops.closure_events(affected_keys, spec), marker, True, None
46
+ )
47
+ existing_events = ops.union([existing_events, stored_tombstones])
39
48
 
40
49
  all_events = ops.union(
41
50
  [
@@ -46,5 +55,21 @@ def apply_log(
46
55
  deduped = ops.dedup_priority(all_events, entity_keys + [eff_col], _ORIGIN_COL)
47
56
  deduped = ops.drop(deduped, [_ORIGIN_COL])
48
57
 
49
- rebuilt = ops.build_log_boundaries(deduped, spec)
58
+ rebuilt = build_log_history(ops, deduped, spec)
50
59
  return ops.union([untouched, rebuilt])
60
+
61
+
62
+ def build_log_history(ops: HistorifyBackend[F], events: F, spec: HistorifySpec) -> F:
63
+ """Build LOG history vectors from an event frame, resolving tombstones.
64
+
65
+ Tombstones take part in boundary computation as events of their own, so the
66
+ vector before each one closes a period earlier; the tombstone rows and the
67
+ ``delete_marker`` column are then dropped, leaving the entity without an
68
+ open vector until its next regular event.
69
+ """
70
+ marker = spec.delete_marker
71
+ if marker is None:
72
+ return ops.build_log_boundaries(events, spec)
73
+ flagged = ops.fill_null(events, marker, False)
74
+ history = ops.build_log_boundaries(flagged, spec)
75
+ return ops.drop(ops.filter_eq(history, marker, False, None), [marker])
@@ -14,6 +14,10 @@ class HistorifyBackend(Protocol[F]):
14
14
 
15
15
  def columns(self, frame: F) -> list[str]: ...
16
16
 
17
+ def non_boolean_dtype(self, frame: F, col: str) -> str | None:
18
+ """Return the dtype name of ``col`` when it is not boolean, else ``None``."""
19
+ ...
20
+
17
21
  def history_dtype(self, spec: HistorifySpec) -> Any:
18
22
  """Return the native dtype for valid_from / valid_to columns."""
19
23
  ...
@@ -40,6 +44,10 @@ class HistorifyBackend(Protocol[F]):
40
44
  """Add null column with given dtype."""
41
45
  ...
42
46
 
47
+ def fill_null(self, frame: F, col: str, value: Any) -> F:
48
+ """Replace nulls in ``col`` with a literal value."""
49
+ ...
50
+
43
51
  def rename(self, frame: F, rename_map: dict[str, str]) -> F:
44
52
  """Rename columns according to mapping."""
45
53
  ...
@@ -77,11 +85,24 @@ class HistorifyBackend(Protocol[F]):
77
85
  """Compute valid_from / valid_to from sorted event frame (LOG mode)."""
78
86
  ...
79
87
 
88
+ def closure_events(self, history: F, spec: HistorifySpec) -> F:
89
+ """Return one tombstone instant per stored vector closed without a successor.
90
+
91
+ LOG history has no gaps except those left by tombstones, so every gap is
92
+ read as a deletion: a vector has no successor when no later vector of its
93
+ entity starts within one period after its ``valid_to``. Each row carries
94
+ ``keys`` and the effective-date column at that next period (the
95
+ tombstone's instant); the caller flags it with ``delete_marker``.
96
+ """
97
+ ...
98
+
80
99
  def apply_delete_policy(self, deleted: F, spec: HistorifySpec, eff_date: Any) -> F: ...
81
100
 
82
101
  def ensure_soft_delete_col(self, result: F, spec: HistorifySpec) -> F: ...
83
102
 
84
- def assert_unique_keys(self, frame: F, keys: list[str]) -> None: ...
103
+ def duplicate_keys(self, frame: F, keys: list[str]) -> str | None:
104
+ """Describe up to five ``keys`` combinations repeated in ``frame``, or ``None``."""
105
+ ...
85
106
 
86
107
  def assert_no_date_collisions(
87
108
  self, frame: F, keys: list[str], eff_col: str, spec: HistorifySpec
@@ -9,11 +9,13 @@ from loom.etl.backends._historify._common import (
9
9
  resolve_effective_date,
10
10
  resolve_track_cols,
11
11
  )
12
- from loom.etl.backends._historify._log import apply_log
12
+ from loom.etl.backends._historify._log import apply_log, build_log_history
13
13
  from loom.etl.backends._historify._ops import HistorifyBackend
14
14
  from loom.etl.backends._historify._snapshot import apply_snapshot
15
15
  from loom.etl.declarative.target._history import (
16
+ HistorifyDeleteMarkerError,
16
17
  HistorifyInputMode,
18
+ HistorifyKeyConflictError,
17
19
  HistorifyRepairReport,
18
20
  HistorifySpec,
19
21
  HistorifyTemporalConflictError,
@@ -44,6 +46,7 @@ def scd2_transform(
44
46
  (SNAPSHOT mode with ``allow_temporal_rerun``), otherwise ``None``.
45
47
 
46
48
  Raises:
49
+ HistorifyDeleteMarkerError: ``delete_marker`` column missing or not boolean.
47
50
  HistorifyKeyConflictError: Duplicate entity state vectors.
48
51
  HistorifyDateCollisionError: Same-date collisions in LOG mode.
49
52
  HistorifyTemporalConflictError: Future-open records, re-weave off.
@@ -52,8 +55,13 @@ def scd2_transform(
52
55
  join_key = list(spec.keys) + list(track_cols)
53
56
  eff_date = resolve_effective_date(spec, params_instance)
54
57
 
58
+ if spec.delete_marker is not None:
59
+ _assert_delete_marker(ops, frame, spec.delete_marker)
55
60
  is_log = spec.mode is HistorifyInputMode.LOG
56
- ops.assert_unique_keys(frame, [*spec.keys, str(spec.effective_date)] if is_log else join_key)
61
+ unique_key = [*spec.keys, str(spec.effective_date)] if is_log else join_key
62
+ duplicates = ops.duplicate_keys(frame, unique_key)
63
+ if duplicates is not None:
64
+ raise HistorifyKeyConflictError(duplicates, mode=spec.mode)
57
65
  if is_log:
58
66
  ops.assert_no_date_collisions(frame, join_key, str(spec.effective_date), spec)
59
67
 
@@ -68,6 +76,17 @@ def scd2_transform(
68
76
  return apply_log(ops, frame, existing, spec), None
69
77
 
70
78
 
79
+ def _assert_delete_marker(ops: HistorifyBackend[F], frame: F, marker: str) -> None:
80
+ """Raise unless the incoming frame carries ``marker`` as a boolean column."""
81
+ if marker not in ops.columns(frame):
82
+ raise HistorifyDeleteMarkerError(marker, "is missing from the incoming frame")
83
+ dtype = ops.non_boolean_dtype(frame, marker)
84
+ if dtype is not None:
85
+ raise HistorifyDeleteMarkerError(
86
+ marker, f"has dtype {dtype}, not boolean; cast it to Boolean (null = regular event)"
87
+ )
88
+
89
+
71
90
  def _first_run(
72
91
  ops: HistorifyBackend[F],
73
92
  frame: F,
@@ -84,7 +103,7 @@ def _first_run(
84
103
  dtype,
85
104
  )
86
105
  return ops.ensure_soft_delete_col(result, spec)
87
- return ops.build_log_boundaries(frame, spec)
106
+ return build_log_history(ops, frame, spec)
88
107
 
89
108
 
90
109
  def _rewind_report_if_enabled(
@@ -12,6 +12,7 @@ from dataclasses import dataclass
12
12
  from typing import TYPE_CHECKING, Any, Generic, TypeVar
13
13
 
14
14
  from loom.core.logger import get_logger
15
+ from loom.etl.backends._historify import HistorifyBackend, scd2_transform
15
16
  from loom.etl.declarative.target import (
16
17
  AppendSpec,
17
18
  ClientSpec,
@@ -421,9 +422,11 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
421
422
  ) -> HistorifyRepairReport | None:
422
423
  """SCD Type 2 historify policy: read existing, validate, transform, write.
423
424
 
424
- Reads existing target data, validates creation rights when absent, then
425
- delegates to :meth:`_historify` with the existing frame so the backend
426
- only handles the transform + write — not the read.
425
+ Reads existing target data, validates creation rights when absent, runs
426
+ :func:`~loom.etl.backends._historify.scd2_transform` with the engine's
427
+ :meth:`_historify_backend`, then writes the rebuilt history. The existing
428
+ frame is dropped before the write, so eager backends release the table
429
+ snapshot instead of holding it alongside the rebuilt history.
427
430
 
428
431
  Args:
429
432
  frame: Incoming input frame.
@@ -435,18 +438,59 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
435
438
  Returns:
436
439
  A :class:`~loom.etl.HistorifyRepairReport` when a re-weave was
437
440
  performed, or ``None`` for a normal forward-only run.
441
+
442
+ Raises:
443
+ HistorifyDeleteMarkerError: ``delete_marker`` missing or not boolean.
444
+ HistorifyKeyConflictError: Duplicate entity state vectors.
445
+ HistorifyDateCollisionError: Same-date ties in LOG mode.
446
+ HistorifyTemporalConflictError: Future-open records detected.
438
447
  """
439
448
  existing = self._read_existing_data(target, frame, spec)
440
- if existing is None:
449
+ create = existing is None
450
+ if create:
441
451
  _ensure_can_create_missing_table(
442
452
  target=target,
443
453
  schema_mode=spec.schema_mode,
444
454
  missing_table_policy=self._missing_table_policy,
445
455
  )
446
456
  materialized = self._materialize_checked(frame, target, streaming=False)
447
- return self._historify(
448
- materialized, existing, target, spec=spec, params_instance=params_instance
457
+ result, report = scd2_transform(
458
+ self._historify_backend(), materialized, existing, spec, params_instance
449
459
  )
460
+ del existing
461
+ if report is not None:
462
+ _log.warning(
463
+ "historify_temporal_rerun",
464
+ target=target.logical_ref.ref,
465
+ affected_key_count=len(report.affected_keys),
466
+ dates_requiring_rerun=[str(d) for d in report.dates_requiring_rerun],
467
+ warnings=list(report.warnings),
468
+ )
469
+ self._write_history(result, target, spec=spec, create=create)
470
+ return report
471
+
472
+ def _write_history(
473
+ self,
474
+ result: WriteFrameT,
475
+ target: ResolvedTarget,
476
+ *,
477
+ spec: HistorifySpec,
478
+ create: bool,
479
+ ) -> None:
480
+ """Write rebuilt history: create the table, or replace its scoped content."""
481
+ if create:
482
+ self._create(
483
+ result,
484
+ target,
485
+ schema_mode=spec.schema_mode,
486
+ partition_cols=spec.partition_scope or (),
487
+ )
488
+ elif spec.partition_scope:
489
+ self._replace_partitions(
490
+ result, target, partition_cols=spec.partition_scope, schema_mode=spec.schema_mode
491
+ )
492
+ else:
493
+ self._replace(result, target, schema_mode=spec.schema_mode)
450
494
 
451
495
  # ========================================================================
452
496
  # Audit Hook (overrideable — default is a no-op)
@@ -664,42 +708,8 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
664
708
  """Matched-only merge into existing table — never inserts."""
665
709
 
666
710
  @abstractmethod
667
- def _historify(
668
- self,
669
- frame: WriteFrameT,
670
- existing: WriteFrameT | None,
671
- target: ResolvedTarget,
672
- *,
673
- spec: HistorifySpec,
674
- params_instance: Any,
675
- ) -> HistorifyRepairReport | None:
676
- """Apply SCD Type 2 transform and write result to target.
677
-
678
- Called after :meth:`_read_existing_data` has already fetched the current
679
- target state. The implementation must:
680
-
681
- * Run the SCD2 algorithm (via :func:`~loom.etl.backends._historify.scd2_transform`).
682
- * Write the result using the existing write hooks (``_create``,
683
- ``_replace``, or ``_replace_partitions``).
684
-
685
- Args:
686
- frame: Materialised incoming frame (write-ready).
687
- existing: Current target frame, or ``None`` for first run.
688
- target: Resolved Delta target.
689
- spec: Compiled historify spec.
690
- params_instance: Runtime params; used to resolve
691
- ``spec.effective_date`` when it is a
692
- :class:`~loom.etl.ParamExpr`.
693
-
694
- Returns:
695
- A :class:`~loom.etl.HistorifyRepairReport` when re-weave was
696
- triggered, or ``None`` for a normal forward-only run.
697
-
698
- Raises:
699
- HistorifyKeyConflictError: Duplicate entity state vectors.
700
- HistorifyDateCollisionError: Same-date ties in LOG mode.
701
- HistorifyTemporalConflictError: Future-open records detected.
702
- """
711
+ def _historify_backend(self) -> HistorifyBackend[WriteFrameT]:
712
+ """Return the SCD2 primitives of this engine."""
703
713
 
704
714
  @abstractmethod
705
715
  def _write_file(
@@ -6,12 +6,11 @@ from typing import Any
6
6
 
7
7
  import polars as pl
8
8
 
9
- from loom.etl.backends._historify._common import prev_period_value
9
+ from loom.etl.backends._historify._common import log_run_cols, prev_period_value
10
10
  from loom.etl.backends.polars._frame import FrameT
11
11
  from loom.etl.declarative.target._history import (
12
12
  DeletePolicy,
13
13
  HistorifyDateCollisionError,
14
- HistorifyKeyConflictError,
15
14
  HistorifySpec,
16
15
  HistoryDateType,
17
16
  )
@@ -21,12 +20,22 @@ def _history_boundary_dtype(spec: HistorifySpec) -> type[pl.Date] | pl.Datetime:
21
20
  return pl.Date if spec.date_type is HistoryDateType.DATE else pl.Datetime("us", "UTC")
22
21
 
23
22
 
23
+ def _period_offset(spec: HistorifySpec) -> pl.Expr:
24
+ if spec.date_type is HistoryDateType.DATE:
25
+ return pl.duration(days=1)
26
+ return pl.duration(microseconds=1)
27
+
28
+
24
29
  class PolarsHistorifyBackend:
25
30
  """Polars implementation of HistorifyBackend."""
26
31
 
27
32
  def columns(self, frame: pl.DataFrame) -> list[str]:
28
33
  return list(frame.columns)
29
34
 
35
+ def non_boolean_dtype(self, frame: pl.DataFrame, col: str) -> str | None:
36
+ dtype = frame.collect_schema()[col]
37
+ return None if dtype == pl.Boolean else str(dtype)
38
+
30
39
  def history_dtype(self, spec: HistorifySpec) -> type[pl.Date] | pl.Datetime:
31
40
  return _history_boundary_dtype(spec)
32
41
 
@@ -74,6 +83,9 @@ class PolarsHistorifyBackend:
74
83
  def null_col(self, frame: pl.DataFrame, name: str, dtype: Any) -> pl.DataFrame:
75
84
  return frame.with_columns(pl.lit(None, dtype=dtype).alias(name))
76
85
 
86
+ def fill_null(self, frame: pl.DataFrame, col: str, value: Any) -> pl.DataFrame:
87
+ return frame.with_columns(pl.col(col).fill_null(value))
88
+
77
89
  def rename(self, frame: pl.DataFrame, rename_map: dict[str, str]) -> pl.DataFrame:
78
90
  return frame.rename(rename_map)
79
91
 
@@ -143,11 +155,7 @@ class PolarsHistorifyBackend:
143
155
  eff_col = str(spec.effective_date)
144
156
  entity_key = list(spec.keys)
145
157
  boundary_dtype = _history_boundary_dtype(spec)
146
- offset = (
147
- pl.duration(days=1)
148
- if spec.date_type is HistoryDateType.DATE
149
- else pl.duration(microseconds=1)
150
- )
158
+ offset = _period_offset(spec)
151
159
 
152
160
  collapsed = self._collapse_same_track_runs(frame, spec, entity_key, eff_col)
153
161
  sorted_events = collapsed.sort(entity_key + [eff_col])
@@ -171,6 +179,24 @@ class PolarsHistorifyBackend:
171
179
  clamped_valid_to.cast(boundary_dtype).alias(spec.valid_to),
172
180
  ).drop(eff_col)
173
181
 
182
+ def closure_events(self, history: pl.DataFrame, spec: HistorifySpec) -> pl.DataFrame:
183
+ entity_key = list(spec.keys)
184
+ closed_at = pl.col(spec.valid_to) + _period_offset(spec)
185
+ next_from = pl.col("__next_from__")
186
+ # Nulls last: a zero-width vector sorts before the vector sharing its valid_from.
187
+ return (
188
+ history.sort([*entity_key, spec.valid_from, spec.valid_to], nulls_last=True)
189
+ .with_columns(pl.col(spec.valid_from).shift(-1).over(entity_key).alias("__next_from__"))
190
+ .filter(
191
+ pl.col(spec.valid_to).is_not_null()
192
+ & (next_from.is_null() | (next_from > closed_at))
193
+ )
194
+ .select(
195
+ *entity_key,
196
+ closed_at.cast(_history_boundary_dtype(spec)).alias(str(spec.effective_date)),
197
+ )
198
+ )
199
+
174
200
  @staticmethod
175
201
  def _collapse_same_track_runs(
176
202
  frame: FrameT,
@@ -187,9 +213,8 @@ class PolarsHistorifyBackend:
187
213
  if spec.track is None:
188
214
  return frame
189
215
 
190
- track = list(spec.track)
191
216
  overwrite: list[str] = list(spec.overwrite or ())
192
- track_struct = pl.struct(track)
217
+ track_struct = pl.struct(log_run_cols(spec))
193
218
 
194
219
  runs = (
195
220
  frame.sort(entity_key + [eff_col])
@@ -242,11 +267,11 @@ class PolarsHistorifyBackend:
242
267
  boundary_dtype = _history_boundary_dtype(spec)
243
268
  return result.with_columns(pl.lit(None, dtype=boundary_dtype).alias(spec.deleted_at))
244
269
 
245
- def assert_unique_keys(self, frame: pl.DataFrame, keys: list[str]) -> None:
270
+ def duplicate_keys(self, frame: pl.DataFrame, keys: list[str]) -> str | None:
246
271
  if len(frame) == frame.select(keys).n_unique():
247
- return
272
+ return None
248
273
  dupes = frame.filter(frame.select(keys).is_duplicated()).select(keys).head(5)
249
- raise HistorifyKeyConflictError(str(dupes.to_dicts()))
274
+ return str(dupes.to_dicts())
250
275
 
251
276
  def assert_no_date_collisions(
252
277
  self,
@@ -10,7 +10,6 @@ from deltalake import CommitProperties, DeltaTable, WriterProperties, write_delt
10
10
  from deltalake.table import TableMerger
11
11
 
12
12
  from loom.core.logger import get_logger
13
- from loom.etl.backends._historify._transform import scd2_transform
14
13
  from loom.etl.backends._merge import (
15
14
  SOURCE_ALIAS,
16
15
  TARGET_ALIAS,
@@ -31,7 +30,7 @@ from loom.etl.backends.polars._schema import (
31
30
  )
32
31
  from loom.etl.declarative.target import SchemaMode
33
32
  from loom.etl.declarative.target._file import FileSpec
34
- from loom.etl.declarative.target._history import HistorifyRepairReport, HistorifySpec
33
+ from loom.etl.declarative.target._history import HistorifySpec
35
34
  from loom.etl.declarative.target._table import (
36
35
  AppendSpec,
37
36
  ReplacePartitionsSpec,
@@ -620,40 +619,8 @@ class PolarsTargetWriter(_WritePolicy[pl.LazyFrame, pl.DataFrame, PolarsPhysical
620
619
  except (TableNotFoundError, FileNotFoundError):
621
620
  return None
622
621
 
623
- def _historify(
624
- self,
625
- frame: pl.DataFrame,
626
- existing: pl.DataFrame | None,
627
- target: ResolvedTarget,
628
- *,
629
- spec: HistorifySpec,
630
- params_instance: Any,
631
- ) -> HistorifyRepairReport | None:
632
- """Run SCD Type 2 transform and write result via existing write hooks."""
633
- result, report = scd2_transform(
634
- PolarsHistorifyBackend(), frame, existing, spec, params_instance
635
- )
636
- if report is not None:
637
- _log.warning(
638
- "historify temporal rerun rewound future history",
639
- affected_key_count=len(report.affected_keys),
640
- dates_requiring_rerun=[str(d) for d in report.dates_requiring_rerun],
641
- warnings=list(report.warnings),
642
- )
643
- if existing is None:
644
- self._create(
645
- result,
646
- target,
647
- schema_mode=spec.schema_mode,
648
- partition_cols=spec.partition_scope or (),
649
- )
650
- elif spec.partition_scope:
651
- self._replace_partitions(
652
- result, target, partition_cols=spec.partition_scope, schema_mode=spec.schema_mode
653
- )
654
- else:
655
- self._replace(result, target, schema_mode=spec.schema_mode)
656
- return report
622
+ def _historify_backend(self) -> PolarsHistorifyBackend:
623
+ return PolarsHistorifyBackend()
657
624
 
658
625
  def _write_file(
659
626
  self,
@@ -4,15 +4,15 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Any
6
6
 
7
- from pyspark.sql import DataFrame
7
+ from pyspark.sql import Column, DataFrame
8
8
  from pyspark.sql import functions as F
9
+ from pyspark.sql.types import BooleanType
9
10
  from pyspark.sql.window import Window
10
11
 
11
- from loom.etl.backends._historify._common import prev_period_value
12
+ from loom.etl.backends._historify._common import log_run_cols, prev_period_value
12
13
  from loom.etl.declarative.target._history import (
13
14
  DeletePolicy,
14
15
  HistorifyDateCollisionError,
15
- HistorifyKeyConflictError,
16
16
  HistorifySpec,
17
17
  HistoryDateType,
18
18
  )
@@ -22,12 +22,22 @@ def _history_boundary_dtype_sql(spec: HistorifySpec) -> str:
22
22
  return "date" if spec.date_type is HistoryDateType.DATE else "timestamp"
23
23
 
24
24
 
25
+ def _next_period(col: Column, spec: HistorifySpec) -> Column:
26
+ if spec.date_type is HistoryDateType.DATE:
27
+ return F.date_add(col, 1)
28
+ return col + F.expr("INTERVAL 1 MICROSECOND")
29
+
30
+
25
31
  class SparkHistorifyBackend:
26
32
  """Spark implementation of HistorifyBackend."""
27
33
 
28
34
  def columns(self, frame: DataFrame) -> list[str]:
29
35
  return list(frame.columns)
30
36
 
37
+ def non_boolean_dtype(self, frame: DataFrame, col: str) -> str | None:
38
+ dtype = frame.schema[col].dataType
39
+ return None if isinstance(dtype, BooleanType) else dtype.simpleString()
40
+
31
41
  def history_dtype(self, spec: HistorifySpec) -> str:
32
42
  return _history_boundary_dtype_sql(spec)
33
43
 
@@ -77,6 +87,9 @@ class SparkHistorifyBackend:
77
87
  def null_col(self, frame: DataFrame, name: str, dtype: Any) -> DataFrame:
78
88
  return frame.withColumn(name, F.lit(None).cast(dtype))
79
89
 
90
+ def fill_null(self, frame: DataFrame, col: str, value: Any) -> DataFrame:
91
+ return frame.withColumn(col, F.coalesce(F.col(col), F.lit(value)))
92
+
80
93
  def rename(self, frame: DataFrame, rename_map: dict[str, str]) -> DataFrame:
81
94
  result = frame
82
95
  for old, new in rename_map.items():
@@ -199,6 +212,25 @@ class SparkHistorifyBackend:
199
212
  .drop(eff_col)
200
213
  )
201
214
 
215
+ def closure_events(self, history: DataFrame, spec: HistorifySpec) -> DataFrame:
216
+ entity_key = list(spec.keys)
217
+ # Nulls last: a zero-width vector sorts before the vector sharing its valid_from.
218
+ window = Window.partitionBy(entity_key).orderBy(
219
+ F.col(spec.valid_from), F.col(spec.valid_to).asc_nulls_last()
220
+ )
221
+ closed_at = _next_period(F.col(spec.valid_to), spec)
222
+ next_from = F.col("__next_from__")
223
+ return (
224
+ history.withColumn("__next_from__", F.lead(spec.valid_from).over(window))
225
+ .filter(
226
+ F.col(spec.valid_to).isNotNull() & (next_from.isNull() | (next_from > closed_at))
227
+ )
228
+ .select(
229
+ *entity_key,
230
+ closed_at.cast(_history_boundary_dtype_sql(spec)).alias(str(spec.effective_date)),
231
+ )
232
+ )
233
+
202
234
  @staticmethod
203
235
  def _collapse_same_track_runs(
204
236
  frame: DataFrame,
@@ -215,9 +247,8 @@ class SparkHistorifyBackend:
215
247
  if spec.track is None:
216
248
  return frame
217
249
 
218
- track = list(spec.track)
219
250
  overwrite = list(spec.overwrite or ())
220
- track_struct = F.struct(*[F.col(c) for c in track])
251
+ track_struct = F.struct(*[F.col(c) for c in log_run_cols(spec)])
221
252
 
222
253
  order_w = Window.partitionBy(entity_key).orderBy(eff_col)
223
254
  prev_struct = F.lag(track_struct).over(order_w)
@@ -264,15 +295,11 @@ class SparkHistorifyBackend:
264
295
  boundary_dtype = _history_boundary_dtype_sql(spec)
265
296
  return result.withColumn(spec.deleted_at, F.lit(None).cast(boundary_dtype))
266
297
 
267
- def assert_unique_keys(self, frame: DataFrame, keys: list[str]) -> None:
268
- n_rows = frame.count()
269
- n_unique = frame.select(keys).distinct().count()
270
- if n_rows == n_unique:
271
- return
298
+ def duplicate_keys(self, frame: DataFrame, keys: list[str]) -> str | None:
272
299
  dupes = (
273
300
  frame.groupBy(keys).count().filter(F.col("count") > 1).drop("count").limit(5).collect()
274
301
  )
275
- raise HistorifyKeyConflictError(str([row.asDict() for row in dupes]))
302
+ return str([row.asDict() for row in dupes]) if dupes else None
276
303
 
277
304
  def assert_no_date_collisions(
278
305
  self,
@@ -15,7 +15,6 @@ from pyspark.sql.column import Column
15
15
  from pyspark.storagelevel import StorageLevel
16
16
 
17
17
  from loom.etl.backends._format_registry import resolve_format_handler, write_options_or_default
18
- from loom.etl.backends._historify._transform import scd2_transform
19
18
  from loom.etl.backends._merge import (
20
19
  SOURCE_ALIAS,
21
20
  TARGET_ALIAS,
@@ -38,7 +37,7 @@ from loom.etl.declarative._write_options import (
38
37
  )
39
38
  from loom.etl.declarative.target import SchemaMode
40
39
  from loom.etl.declarative.target._file import FileSpec
41
- from loom.etl.declarative.target._history import HistorifyRepairReport, HistorifySpec
40
+ from loom.etl.declarative.target._history import HistorifySpec
42
41
  from loom.etl.declarative.target._table import AppendSpec, UpdateSpec, UpsertSpec
43
42
  from loom.etl.lineage._records import LineageRecord, get_lineage_schema
44
43
  from loom.etl.storage._config import MissingTablePolicy
@@ -404,41 +403,8 @@ class SparkTargetWriter(_WritePolicy[DataFrame, DataFrame, SparkPhysicalSchema])
404
403
  return self._spark.read.format("delta").load(target.location.uri)
405
404
  return None
406
405
 
407
- def _historify(
408
- self,
409
- frame: DataFrame,
410
- existing: DataFrame | None,
411
- target: ResolvedTarget,
412
- *,
413
- spec: HistorifySpec,
414
- params_instance: Any,
415
- ) -> HistorifyRepairReport | None:
416
- """Run SCD Type 2 transform and write result via existing write hooks."""
417
- result, report = scd2_transform(
418
- SparkHistorifyBackend(), frame, existing, spec, params_instance
419
- )
420
- if report is not None:
421
- _log.warning(
422
- "historify temporal rerun rewound future history: "
423
- "affected_key_count=%d dates_requiring_rerun=%s warnings=%s",
424
- len(report.affected_keys),
425
- [str(d) for d in report.dates_requiring_rerun],
426
- list(report.warnings),
427
- )
428
- if existing is None:
429
- self._create(
430
- result,
431
- target,
432
- schema_mode=spec.schema_mode,
433
- partition_cols=spec.partition_scope or (),
434
- )
435
- elif spec.partition_scope:
436
- self._replace_partitions(
437
- result, target, partition_cols=spec.partition_scope, schema_mode=spec.schema_mode
438
- )
439
- else:
440
- self._replace(result, target, schema_mode=spec.schema_mode)
441
- return report
406
+ def _historify_backend(self) -> SparkHistorifyBackend:
407
+ return SparkHistorifyBackend()
442
408
 
443
409
  def _write_file(
444
410
  self,