loom-kernel 0.18.2__tar.gz → 1.0.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 (961) hide show
  1. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/CHANGELOG.md +29 -0
  2. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/PKG-INFO +1 -1
  3. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/rest/identity.md +1 -1
  4. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/rest/sql.md +18 -4
  5. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/pyproject.toml +3 -3
  6. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/identity/__init__.py +3 -0
  7. loom_kernel-1.0.0/src/loom/core/identity/issuer.py +70 -0
  8. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/auth/__init__.py +4 -2
  9. loom_kernel-1.0.0/src/loom/rest/auth/config.py +317 -0
  10. loom_kernel-1.0.0/src/loom/rest/auth/jwt.py +431 -0
  11. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_app_hardening.py +5 -1
  12. loom_kernel-1.0.0/tests/unit/rest/test_jwt_issuer.py +615 -0
  13. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_jwt_middleware.py +55 -19
  14. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_sql_endpoint_auth_gate.py +6 -2
  15. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_sql_endpoint_roles.py +5 -1
  16. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/uv.lock +3 -3
  17. loom_kernel-0.18.2/src/loom/rest/auth/config.py +0 -111
  18. loom_kernel-0.18.2/src/loom/rest/auth/jwt.py +0 -192
  19. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/.github/workflows/ci-main.yml +0 -0
  20. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/.github/workflows/ci-pr.yml +0 -0
  21. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/.github/workflows/docs.yml +0 -0
  22. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/.github/workflows/release.yml +0 -0
  23. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/.gitignore +0 -0
  24. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/.pre-commit-config.yaml +0 -0
  25. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/.readthedocs.yaml +0 -0
  26. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/LICENSE +0 -0
  27. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/Makefile +0 -0
  28. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/README.md +0 -0
  29. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/codecov.yml +0 -0
  30. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docker-compose.local.yaml +0 -0
  31. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/_static/.gitkeep +0 -0
  32. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/_static/custom.css +0 -0
  33. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/_static/logo-transparent.png +0 -0
  34. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/_static/logo.svg +0 -0
  35. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/architecture/adr/README.md +0 -0
  36. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/architecture/clean-architecture.md +0 -0
  37. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/architecture/overview.md +0 -0
  38. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/conf.py +0 -0
  39. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/etl/examples.md +0 -0
  40. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/etl/pipelines.md +0 -0
  41. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/etl/testing.md +0 -0
  42. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/examples-repo/index.md +0 -0
  43. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/getting-started/etl.md +0 -0
  44. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/getting-started/rest.md +0 -0
  45. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/getting-started/streaming.md +0 -0
  46. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/guides/autocrud.md +0 -0
  47. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/guides/celery.md +0 -0
  48. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/guides/etl.md +0 -0
  49. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/guides/fake-repo-examples.md +0 -0
  50. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/guides/quickstart.md +0 -0
  51. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/guides/use-case-dsl.md +0 -0
  52. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/index.rst +0 -0
  53. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/overview.md +0 -0
  54. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/reference/api/core.rst +0 -0
  55. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/reference/api/etl.rst +0 -0
  56. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/reference/api/repository.rst +0 -0
  57. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/reference/api/rest.rst +0 -0
  58. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/reference/api/streaming.rst +0 -0
  59. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/reference/api/testing.rst +0 -0
  60. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/reference/index.rst +0 -0
  61. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/requirements.txt +0 -0
  62. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/rest/autocrud.md +0 -0
  63. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/rest/celery.md +0 -0
  64. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/rest/examples.md +0 -0
  65. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/rest/testing.md +0 -0
  66. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/rest/use-case-dsl.md +0 -0
  67. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/docs/streaming/bytewax.md +0 -0
  68. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/scripts/release/checkout_merged_release.py +0 -0
  69. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/sonar-project.properties +0 -0
  70. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/__init__.py +0 -0
  71. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/celery/__init__.py +0 -0
  72. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/celery/auto.py +0 -0
  73. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/celery/bootstrap.py +0 -0
  74. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/celery/config.py +0 -0
  75. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/celery/constants.py +0 -0
  76. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/celery/runner.py +0 -0
  77. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/celery/service.py +0 -0
  78. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/async_bridge.py +0 -0
  79. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/backend/__init__.py +0 -0
  80. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/backend/core_model.py +0 -0
  81. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/backend/protocol.py +0 -0
  82. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/backend/sqlalchemy.py +0 -0
  83. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/bootstrap/__init__.py +0 -0
  84. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
  85. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/bootstrap/kernel.py +0 -0
  86. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/__init__.py +0 -0
  87. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/abc/__init__.py +0 -0
  88. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/abc/backend.py +0 -0
  89. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/abc/config.py +0 -0
  90. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/abc/dependency.py +0 -0
  91. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/codec.py +0 -0
  92. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/decorators.py +0 -0
  93. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/dependency.py +0 -0
  94. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/gateway.py +0 -0
  95. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/keys.py +0 -0
  96. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/repository.py +0 -0
  97. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/cache/serializer.py +0 -0
  98. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/command/__init__.py +0 -0
  99. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/command/adapter.py +0 -0
  100. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/command/base.py +0 -0
  101. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/command/field.py +0 -0
  102. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/command/introspection.py +0 -0
  103. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/compiler.py +0 -0
  104. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/__init__.py +0 -0
  105. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/_resolver_utils.py +0 -0
  106. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/binder.py +0 -0
  107. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/configurable.py +0 -0
  108. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/context.py +0 -0
  109. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/errors.py +0 -0
  110. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/keys.py +0 -0
  111. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/loader.py +0 -0
  112. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/model.py +0 -0
  113. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/observability.py +0 -0
  114. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/resolver.py +0 -0
  115. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/secrets.py +0 -0
  116. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/config/ssm.py +0 -0
  117. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/contracts/__init__.py +0 -0
  118. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/contracts/manifest.py +0 -0
  119. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/di/__init__.py +0 -0
  120. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/di/container.py +0 -0
  121. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/di/scope.py +0 -0
  122. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/discovery/__init__.py +0 -0
  123. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/discovery/_utils.py +0 -0
  124. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/discovery/base.py +0 -0
  125. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/discovery/interfaces.py +0 -0
  126. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/discovery/manifest.py +0 -0
  127. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/discovery/modules.py +0 -0
  128. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/engine/__init__.py +0 -0
  129. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/engine/compilable.py +0 -0
  130. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/engine/compiler.py +0 -0
  131. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/engine/events.py +0 -0
  132. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/engine/executor.py +0 -0
  133. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/engine/metrics.py +0 -0
  134. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/engine/plan.py +0 -0
  135. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/errors/__init__.py +0 -0
  136. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/errors/codes.py +0 -0
  137. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/errors/errors.py +0 -0
  138. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/expr/__init__.py +0 -0
  139. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/expr/eval.py +0 -0
  140. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/expr/nodes.py +0 -0
  141. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/expr/refs.py +0 -0
  142. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/identity/context.py +0 -0
  143. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/identity/identity.py +0 -0
  144. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/identity/wire.py +0 -0
  145. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/job/__init__.py +0 -0
  146. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/job/callback.py +0 -0
  147. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/job/context.py +0 -0
  148. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/job/handle.py +0 -0
  149. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/job/job.py +0 -0
  150. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/job/service.py +0 -0
  151. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/logger/__init__.py +0 -0
  152. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/logger/abc.py +0 -0
  153. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/logger/config.py +0 -0
  154. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/logger/registry.py +0 -0
  155. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/logger/structlogger.py +0 -0
  156. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/__init__.py +0 -0
  157. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/base.py +0 -0
  158. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/enums.py +0 -0
  159. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/field.py +0 -0
  160. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/introspection.py +0 -0
  161. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/projection.py +0 -0
  162. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/relation.py +0 -0
  163. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/struct.py +0 -0
  164. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/timestamped.py +0 -0
  165. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/types.py +0 -0
  166. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/model/types_postgres.py +0 -0
  167. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/__init__.py +0 -0
  168. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/config.py +0 -0
  169. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/event.py +0 -0
  170. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/observer/__init__.py +0 -0
  171. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/observer/noop.py +0 -0
  172. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/observer/otel.py +0 -0
  173. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/observer/structlog.py +0 -0
  174. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/protocol.py +0 -0
  175. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/runtime.py +0 -0
  176. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/observability/topology.py +0 -0
  177. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/projection/__init__.py +0 -0
  178. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/projection/loaders.py +0 -0
  179. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/projection/runtime.py +0 -0
  180. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/__init__.py +0 -0
  181. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/abc/__init__.py +0 -0
  182. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/abc/query.py +0 -0
  183. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  184. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/abc/repository.py +0 -0
  185. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
  186. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
  187. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
  188. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
  189. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/mutation.py +0 -0
  190. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/registration.py +0 -0
  191. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/registry.py +0 -0
  192. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  193. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  194. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  195. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
  196. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  197. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  198. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  199. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  200. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  201. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  202. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  203. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
  204. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  205. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  206. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  207. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  208. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  209. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
  210. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  211. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  212. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/response/__init__.py +0 -0
  213. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/response/base.py +0 -0
  214. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/routing/__init__.py +0 -0
  215. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/routing/ref.py +0 -0
  216. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/routing/resolver.py +0 -0
  217. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/runner.py +0 -0
  218. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/schema/__init__.py +0 -0
  219. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/schema/schema_mode.py +0 -0
  220. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/__init__.py +0 -0
  221. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/abc/__init__.py +0 -0
  222. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/abc/contracts.py +0 -0
  223. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/abc/errors.py +0 -0
  224. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
  225. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
  226. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
  227. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
  228. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/config.py +0 -0
  229. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/sql/service.py +0 -0
  230. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/tracing/__init__.py +0 -0
  231. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/tracing/context.py +0 -0
  232. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/transport/__init__.py +0 -0
  233. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/transport/adapter.py +0 -0
  234. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/uow/__init__.py +0 -0
  235. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/uow/abc.py +0 -0
  236. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/uow/context.py +0 -0
  237. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/__init__.py +0 -0
  238. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/_predicates.py +0 -0
  239. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/compute.py +0 -0
  240. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/constants.py +0 -0
  241. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/factory.py +0 -0
  242. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/field_ref.py +0 -0
  243. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/invoker.py +0 -0
  244. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/keys.py +0 -0
  245. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/markers.py +0 -0
  246. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/registry.py +0 -0
  247. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/rule.py +0 -0
  248. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/core/use_case/use_case.py +0 -0
  249. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/__init__.py +0 -0
  250. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/__init__.py +0 -0
  251. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_format_registry.py +0 -0
  252. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
  253. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_historify/_common.py +0 -0
  254. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_historify/_log.py +0 -0
  255. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
  256. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
  257. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
  258. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_merge.py +0 -0
  259. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_predicate.py +0 -0
  260. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  261. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  262. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  263. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/_write_policy.py +0 -0
  264. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/__init__.py +0 -0
  265. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  266. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  267. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_historify.py +0 -0
  268. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  269. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_reader.py +0 -0
  270. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  271. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  272. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
  273. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/_writer.py +0 -0
  274. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/polars/provider.py +0 -0
  275. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  276. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  277. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/spark/_historify.py +0 -0
  278. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  279. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  280. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  281. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/spark/_writer.py +0 -0
  282. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/backends/spark/provider.py +0 -0
  283. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/checkpoint/__init__.py +0 -0
  284. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
  285. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  286. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
  287. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  288. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  289. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/checkpoint/_store.py +0 -0
  290. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/compiler/__init__.py +0 -0
  291. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/compiler/_binding.py +0 -0
  292. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/compiler/_compiler.py +0 -0
  293. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/compiler/_errors.py +0 -0
  294. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/compiler/_plan.py +0 -0
  295. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/compiler/_validators.py +0 -0
  296. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  297. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/compiler/_validators_step.py +0 -0
  298. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/__init__.py +0 -0
  299. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/_format.py +0 -0
  300. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/_read_options.py +0 -0
  301. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/_utils.py +0 -0
  302. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/_write_options.py +0 -0
  303. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  304. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  305. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  306. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  307. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
  308. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/source/__init__.py +0 -0
  309. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/source/_from.py +0 -0
  310. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
  311. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
  312. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
  313. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/source/_specs.py +0 -0
  314. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/__init__.py +0 -0
  315. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_client.py +0 -0
  316. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_file.py +0 -0
  317. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
  318. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
  319. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
  320. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
  321. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
  322. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
  323. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_into.py +0 -0
  324. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
  325. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_table.py +0 -0
  326. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  327. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/executor/__init__.py +0 -0
  328. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  329. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/executor/_executor.py +0 -0
  330. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/__init__.py +0 -0
  331. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/_registry.py +0 -0
  332. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/__init__.py +0 -0
  333. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
  334. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
  335. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
  336. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
  337. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_mongo.py +0 -0
  338. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
  339. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
  340. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
  341. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/sources/_serialization.py +0 -0
  342. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/targets/__init__.py +0 -0
  343. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
  344. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/lineage/__init__.py +0 -0
  345. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/lineage/_config.py +0 -0
  346. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/lineage/_observer.py +0 -0
  347. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/lineage/_records.py +0 -0
  348. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
  349. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
  350. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
  351. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
  352. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/maintenance/__init__.py +0 -0
  353. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/maintenance/_builder.py +0 -0
  354. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/maintenance/_ops.py +0 -0
  355. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/maintenance/_protocol.py +0 -0
  356. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/maintenance/_runner.py +0 -0
  357. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/maintenance/_step.py +0 -0
  358. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
  359. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
  360. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/__init__.py +0 -0
  361. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/_generics.py +0 -0
  362. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/_params.py +0 -0
  363. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  364. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/_process.py +0 -0
  365. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/_sql.py +0 -0
  366. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/_step.py +0 -0
  367. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/_step_client.py +0 -0
  368. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  369. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runner/__init__.py +0 -0
  370. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runner/_providers.py +0 -0
  371. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runner/_wiring.py +0 -0
  372. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runner/config_loader.py +0 -0
  373. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runner/core.py +0 -0
  374. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runner/errors.py +0 -0
  375. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runner/filtering.py +0 -0
  376. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runtime/__init__.py +0 -0
  377. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/runtime/contracts.py +0 -0
  378. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/schema/__init__.py +0 -0
  379. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/schema/_contract.py +0 -0
  380. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/schema/_schema.py +0 -0
  381. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/storage/__init__.py +0 -0
  382. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/storage/_config.py +0 -0
  383. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/storage/_file_locator.py +0 -0
  384. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/storage/_locator.py +0 -0
  385. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/storage/routing.py +0 -0
  386. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/testing/__init__.py +0 -0
  387. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/testing/_result.py +0 -0
  388. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/testing/_runners.py +0 -0
  389. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/testing/_scenario.py +0 -0
  390. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/testing/_stubs.py +0 -0
  391. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/etl/testing/spark.py +0 -0
  392. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/__init__.py +0 -0
  393. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/_async.py +0 -0
  394. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/_config.py +0 -0
  395. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/_ctx.py +0 -0
  396. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/_meta.py +0 -0
  397. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/_placeholders.py +0 -0
  398. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/_summary.py +0 -0
  399. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/deploy/__init__.py +0 -0
  400. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/deploy/_discovery.py +0 -0
  401. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/deploy/_schedule.py +0 -0
  402. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/deploy/_yaml.py +0 -0
  403. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/__init__.py +0 -0
  404. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_assemble.py +0 -0
  405. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_backfill.py +0 -0
  406. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
  407. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_body.py +0 -0
  408. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_common.py +0 -0
  409. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_factory.py +0 -0
  410. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_hooks.py +0 -0
  411. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_maintenance.py +0 -0
  412. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_run_name.py +0 -0
  413. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_runtime.py +0 -0
  414. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_signature.py +0 -0
  415. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/flow/_stages.py +0 -0
  416. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/manifest/__init__.py +0 -0
  417. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/manifest/_model.py +0 -0
  418. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/manifest/_s3.py +0 -0
  419. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/manifest/_store.py +0 -0
  420. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/notify/__init__.py +0 -0
  421. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/notify/_event.py +0 -0
  422. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/notify/_factory.py +0 -0
  423. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/notify/_port.py +0 -0
  424. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/notify/_slack.py +0 -0
  425. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/observer/__init__.py +0 -0
  426. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/observer/_flow.py +0 -0
  427. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
  428. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/observer/_manifest.py +0 -0
  429. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prefect/observer/_task_run.py +0 -0
  430. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prometheus/__init__.py +0 -0
  431. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prometheus/adapter.py +0 -0
  432. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prometheus/kafka.py +0 -0
  433. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prometheus/lifecycle.py +0 -0
  434. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/prometheus/middleware.py +0 -0
  435. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/py.typed +0 -0
  436. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/__init__.py +0 -0
  437. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/_body.py +0 -0
  438. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/adapter.py +0 -0
  439. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/auth/abc.py +0 -0
  440. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/auth/middleware.py +0 -0
  441. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/autocrud.py +0 -0
  442. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/compiler.py +0 -0
  443. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/constants.py +0 -0
  444. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/cors.py +0 -0
  445. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/errors.py +0 -0
  446. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/__init__.py +0 -0
  447. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/_errors.py +0 -0
  448. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
  449. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/_sql_roles.py +0 -0
  450. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/app.py +0 -0
  451. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/auto.py +0 -0
  452. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/openapi.py +0 -0
  453. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/response.py +0 -0
  454. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
  455. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/fastapi/sql.py +0 -0
  456. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/middleware.py +0 -0
  457. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/model.py +0 -0
  458. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/rest/rest_adapter.py +0 -0
  459. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/__init__.py +0 -0
  460. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/__init__.py +0 -0
  461. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
  462. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
  463. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
  464. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
  465. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/_operators.py +0 -0
  466. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
  467. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
  468. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
  469. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
  470. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
  471. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
  472. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
  473. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
  474. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
  475. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
  476. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
  477. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
  478. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/bytewax/runner.py +0 -0
  479. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/compiler/__init__.py +0 -0
  480. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/compiler/_bindings.py +0 -0
  481. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/compiler/_compiler.py +0 -0
  482. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/compiler/_plan.py +0 -0
  483. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
  484. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
  485. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/core/__init__.py +0 -0
  486. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/core/_errors.py +0 -0
  487. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/core/_exceptions.py +0 -0
  488. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/core/_message.py +0 -0
  489. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/core/_typing.py +0 -0
  490. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/graph/__init__.py +0 -0
  491. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/graph/_flow.py +0 -0
  492. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/__init__.py +0 -0
  493. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/_codec.py +0 -0
  494. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/_config.py +0 -0
  495. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/_errors.py +0 -0
  496. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
  497. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/_message.py +0 -0
  498. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/_record.py +0 -0
  499. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/_wire.py +0 -0
  500. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
  501. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
  502. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
  503. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
  504. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
  505. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
  506. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
  507. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
  508. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/mongo/__init__.py +0 -0
  509. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
  510. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/mongo/_config.py +0 -0
  511. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/mongo/_event.py +0 -0
  512. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/mongo/_normalize.py +0 -0
  513. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/__init__.py +0 -0
  514. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_boundary.py +0 -0
  515. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
  516. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
  517. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_decompose.py +0 -0
  518. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
  519. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
  520. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_fork.py +0 -0
  521. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_helpers.py +0 -0
  522. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_mongo.py +0 -0
  523. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_protocols.py +0 -0
  524. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_router.py +0 -0
  525. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_shape.py +0 -0
  526. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_sink.py +0 -0
  527. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_step.py +0 -0
  528. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
  529. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_table/common.py +0 -0
  530. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_table/config.py +0 -0
  531. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/_with.py +0 -0
  532. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/nodes/refs.py +0 -0
  533. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/streaming/testing.py +0 -0
  534. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/testing/__init__.py +0 -0
  535. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/testing/golden.py +0 -0
  536. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/testing/http_harness.py +0 -0
  537. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/testing/in_memory.py +0 -0
  538. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/testing/repository_harness.py +0 -0
  539. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/src/loom/testing/runner.py +0 -0
  540. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/__init__.py +0 -0
  541. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/conftest.py +0 -0
  542. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/golden/__init__.py +0 -0
  543. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/golden/baselines/.gitkeep +0 -0
  544. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/golden/outputs/.gitkeep +0 -0
  545. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/golden/plans/.gitkeep +0 -0
  546. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/helpers/__init__.py +0 -0
  547. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/__init__.py +0 -0
  548. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/celery_bootstrap/__init__.py +0 -0
  549. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +0 -0
  550. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +0 -0
  551. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +0 -0
  552. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/conftest.py +0 -0
  553. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/__init__.py +0 -0
  554. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/bootstrap/__init__.py +0 -0
  555. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/bootstrap/test_bootstrap_integration.py +0 -0
  556. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/repository/__init__.py +0 -0
  557. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/repository/sqlalchemy/__init__.py +0 -0
  558. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
  559. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
  560. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +0 -0
  561. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/rest/__init__.py +0 -0
  562. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/rest/test_auto_interface_integration.py +0 -0
  563. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/rest/test_fastapi_app_integration.py +0 -0
  564. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/rest/test_rest_error_mapping.py +0 -0
  565. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/rest/test_rest_observability.py +0 -0
  566. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/use_case/__init__.py +0 -0
  567. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/use_case/test_custom_repository_integration.py +0 -0
  568. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
  569. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/etl/__init__.py +0 -0
  570. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/etl/test_runner_integration.py +0 -0
  571. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/__init__.py +0 -0
  572. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/config/__init__.py +0 -0
  573. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -0
  574. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/config/conf.manifest.yaml +0 -0
  575. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/config/conf.modules.yaml +0 -0
  576. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/config/conf.yaml +0 -0
  577. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/main.py +0 -0
  578. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/manifest.py +0 -0
  579. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/__init__.py +0 -0
  580. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/category/__init__.py +0 -0
  581. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/category/model.py +0 -0
  582. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
  583. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/interface.py +0 -0
  584. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/jobs.py +0 -0
  585. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/model.py +0 -0
  586. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/relations.py +0 -0
  587. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/repository.py +0 -0
  588. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/repository_contract.py +0 -0
  589. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/review/__init__.py +0 -0
  590. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/review/model.py +0 -0
  591. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
  592. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/schemas.py +0 -0
  593. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/fake_repo/product/use_cases.py +0 -0
  594. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/sql/__init__.py +0 -0
  595. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/sql/init/01_users_roles.sql +0 -0
  596. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/sql/test_clickhouse_integration.py +0 -0
  597. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/streaming/__init__.py +0 -0
  598. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/streaming/test_into_table_integration.py +0 -0
  599. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/support/__init__.py +0 -0
  600. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/integration/support/logical_repo_fixtures.py +0 -0
  601. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/__init__.py +0 -0
  602. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_bootstrap/__init__.py +0 -0
  603. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_bootstrap/test_async_runtime.py +0 -0
  604. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_bootstrap/test_bootstrap.py +0 -0
  605. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_jobs/__init__.py +0 -0
  606. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_jobs/test_auto.py +0 -0
  607. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_jobs/test_celery_service.py +0 -0
  608. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_jobs/test_config.py +0 -0
  609. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_jobs/test_identity_propagation.py +0 -0
  610. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/celery_jobs/test_runner.py +0 -0
  611. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/ci/test_workflow_supply_chain_contract.py +0 -0
  612. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/__init__.py +0 -0
  613. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/backend/__init__.py +0 -0
  614. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/backend/test_backend_compiler.py +0 -0
  615. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/bootstrap/__init__.py +0 -0
  616. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/bootstrap/test_bootstrap.py +0 -0
  617. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +0 -0
  618. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/bootstrap/test_kernel.py +0 -0
  619. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/cache/__init__.py +0 -0
  620. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/cache/test_cached_repository.py +0 -0
  621. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/command/__init__.py +0 -0
  622. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/command/test_command_base.py +0 -0
  623. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/command/test_command_field.py +0 -0
  624. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/command/test_command_patch.py +0 -0
  625. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/command/test_introspection.py +0 -0
  626. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/config/__init__.py +0 -0
  627. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/config/test_binder.py +0 -0
  628. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/config/test_config.py +0 -0
  629. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/config/test_configurable.py +0 -0
  630. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/config/test_context.py +0 -0
  631. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/config/test_resolver_utils.py +0 -0
  632. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/config/test_secrets.py +0 -0
  633. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/config/test_ssm.py +0 -0
  634. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/di/__init__.py +0 -0
  635. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/di/test_container.py +0 -0
  636. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/discovery/__init__.py +0 -0
  637. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/discovery/test_manifest.py +0 -0
  638. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/engine/__init__.py +0 -0
  639. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/engine/test_caller_binding.py +0 -0
  640. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/engine/test_compiler.py +0 -0
  641. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/engine/test_executor.py +0 -0
  642. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
  643. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/engine/test_executor_uow.py +0 -0
  644. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/engine/test_metrics.py +0 -0
  645. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/engine/test_plan.py +0 -0
  646. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/errors/__init__.py +0 -0
  647. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/errors/test_errors.py +0 -0
  648. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/expr/__init__.py +0 -0
  649. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/expr/test_expr.py +0 -0
  650. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/identity/__init__.py +0 -0
  651. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/identity/test_context.py +0 -0
  652. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/identity/test_identity.py +0 -0
  653. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/identity/test_wire.py +0 -0
  654. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/job/__init__.py +0 -0
  655. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/job/conftest.py +0 -0
  656. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/job/test_callback.py +0 -0
  657. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/job/test_context.py +0 -0
  658. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/job/test_handle.py +0 -0
  659. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/job/test_inline_service.py +0 -0
  660. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/job/test_job.py +0 -0
  661. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/logger/__init__.py +0 -0
  662. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/logger/test_config.py +0 -0
  663. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/logger/test_registry.py +0 -0
  664. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/model/__init__.py +0 -0
  665. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/model/test_model.py +0 -0
  666. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/model/test_struct.py +0 -0
  667. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/model/test_timestamped.py +0 -0
  668. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/observability/__init__.py +0 -0
  669. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/observability/test_observers.py +0 -0
  670. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/observability/test_runtime.py +0 -0
  671. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/projection/__init__.py +0 -0
  672. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/projection/test_runtime.py +0 -0
  673. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/__init__.py +0 -0
  674. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/abc/__init__.py +0 -0
  675. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/abc/conftest.py +0 -0
  676. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/abc/test_query.py +0 -0
  677. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
  678. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/dynamodb/__init__.py +0 -0
  679. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/dynamodb/conftest.py +0 -0
  680. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/dynamodb/test_registry.py +0 -0
  681. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/dynamodb/test_repository.py +0 -0
  682. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/sqlalchemy/__init__.py +0 -0
  683. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
  684. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/sqlalchemy/test_loaders.py +0 -0
  685. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +0 -0
  686. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
  687. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/routing/__init__.py +0 -0
  688. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/routing/test_routing.py +0 -0
  689. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/__init__.py +0 -0
  690. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/_fakes.py +0 -0
  691. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/conftest.py +0 -0
  692. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/test_clickhouse_executor.py +0 -0
  693. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/test_clickhouse_transport.py +0 -0
  694. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/test_config.py +0 -0
  695. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/test_isolation.py +0 -0
  696. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/test_null_service.py +0 -0
  697. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/test_pagination_limits.py +0 -0
  698. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/test_registry_lifecycle.py +0 -0
  699. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/sql/test_role_policy.py +0 -0
  700. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/test_async_bridge.py +0 -0
  701. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/test_compiler_contracts.py +0 -0
  702. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/test_runner_contracts.py +0 -0
  703. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/tracing/__init__.py +0 -0
  704. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/tracing/test_context.py +0 -0
  705. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/uow/__init__.py +0 -0
  706. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
  707. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
  708. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
  709. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/use_case/__init__.py +0 -0
  710. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/use_case/test_compute.py +0 -0
  711. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/use_case/test_factory.py +0 -0
  712. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
  713. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/use_case/test_invoker.py +0 -0
  714. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/use_case/test_markers.py +0 -0
  715. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/use_case/test_rule.py +0 -0
  716. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/core/use_case/test_use_case.py +0 -0
  717. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/__init__.py +0 -0
  718. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/__init__.py +0 -0
  719. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/_historify_contract.py +0 -0
  720. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_empty_write_warning.py +0 -0
  721. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_historify_common.py +0 -0
  722. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/__init__.py +0 -0
  723. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/conftest.py +0 -0
  724. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_apply_schema.py +0 -0
  725. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_backend.py +0 -0
  726. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_dtype.py +0 -0
  727. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_file_writer.py +0 -0
  728. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_historify_polars.py +0 -0
  729. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_predicate_pushdown.py +0 -0
  730. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_reader_columns.py +0 -0
  731. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +0 -0
  732. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_step_execution.py +0 -0
  733. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_streaming_write.py +0 -0
  734. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_upsert_writer.py +0 -0
  735. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_writer_null_schema.py +0 -0
  736. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_polars/test_writer_to_frame.py +0 -0
  737. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_spark/__init__.py +0 -0
  738. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_spark/conftest.py +0 -0
  739. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_spark/test_dtype.py +0 -0
  740. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_spark/test_historify_spark.py +0 -0
  741. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_spark/test_spark_apply_schema.py +0 -0
  742. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_spark/test_step_execution.py +0 -0
  743. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_spark/test_writer_to_frame.py +0 -0
  744. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/backends/test_write_policy_historify.py +0 -0
  745. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/checkpoint/__init__.py +0 -0
  746. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/checkpoint/backends/__init__.py +0 -0
  747. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/checkpoint/backends/test_checkpoint_polars.py +0 -0
  748. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/checkpoint/test_checkpoint_paths.py +0 -0
  749. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/checkpoint/test_cleaners.py +0 -0
  750. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/checkpoint/test_store.py +0 -0
  751. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/client_step/__init__.py +0 -0
  752. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/client_step/test_client_step.py +0 -0
  753. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/__init__.py +0 -0
  754. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_catalog_validator.py +0 -0
  755. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_compiler.py +0 -0
  756. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_compiler_catalog.py +0 -0
  757. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_compiler_upsert.py +0 -0
  758. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_errors.py +0 -0
  759. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_errors_additional_factories.py +0 -0
  760. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_errors_runtime_factories.py +0 -0
  761. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_historify_validator.py +0 -0
  762. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_param_exprs_validator.py +0 -0
  763. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_plan_traversal.py +0 -0
  764. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_step_validator.py +0 -0
  765. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_structural.py +0 -0
  766. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_temp_validator.py +0 -0
  767. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/compiler/test_upsert_validator.py +0 -0
  768. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/conftest.py +0 -0
  769. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/__init__.py +0 -0
  770. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/__init__.py +0 -0
  771. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_clickhouse_reader.py +0 -0
  772. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_dynamodb_predicate.py +0 -0
  773. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_dynamodb_reader.py +0 -0
  774. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_from_clickhouse.py +0 -0
  775. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_from_dynamodb.py +0 -0
  776. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_from_mongo.py +0 -0
  777. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_mongo_predicate.py +0 -0
  778. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_mongo_reader.py +0 -0
  779. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/sources/test_mongo_reader_memory.py +0 -0
  780. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/targets/__init__.py +0 -0
  781. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/targets/test_clickhouse_writer.py +0 -0
  782. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/targets/test_into_clickhouse.py +0 -0
  783. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/test_history_target.py +0 -0
  784. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/test_registry.py +0 -0
  785. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/test_source.py +0 -0
  786. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/test_source_json.py +0 -0
  787. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/test_source_options.py +0 -0
  788. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/test_target.py +0 -0
  789. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/test_utils.py +0 -0
  790. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/io/test_variants.py +0 -0
  791. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/lineage/test_observer.py +0 -0
  792. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/lineage/test_records.py +0 -0
  793. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/lineage/test_store.py +0 -0
  794. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/maintenance/__init__.py +0 -0
  795. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/maintenance/backends/__init__.py +0 -0
  796. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/maintenance/backends/test_delta_rs.py +0 -0
  797. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/maintenance/conftest.py +0 -0
  798. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/maintenance/test_builder.py +0 -0
  799. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/maintenance/test_runner.py +0 -0
  800. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/maintenance/test_step.py +0 -0
  801. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/pipeline/__init__.py +0 -0
  802. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/pipeline/test_pipeline_process.py +0 -0
  803. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/pipeline/test_proxy.py +0 -0
  804. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/pipeline/test_step.py +0 -0
  805. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/schema/__init__.py +0 -0
  806. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/schema/test_contract.py +0 -0
  807. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/schema/test_schema.py +0 -0
  808. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/schema/test_table.py +0 -0
  809. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/sql/__init__.py +0 -0
  810. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/sql/test_merge.py +0 -0
  811. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/sql/test_predicate.py +0 -0
  812. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/sql/test_predicate_dialect.py +0 -0
  813. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/sql/test_sql_runtime.py +0 -0
  814. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/storage/__init__.py +0 -0
  815. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/storage/test_backend_factory.py +0 -0
  816. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/storage/test_io_protocols.py +0 -0
  817. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/storage/test_locator.py +0 -0
  818. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/storage/test_observability_and_protocols.py +0 -0
  819. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/storage/test_route_build.py +0 -0
  820. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/storage/test_schema_readers.py +0 -0
  821. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/storage/test_storage_config.py +0 -0
  822. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_config_loader.py +0 -0
  823. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_executor.py +0 -0
  824. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_format_registry.py +0 -0
  825. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_module_contracts.py +0 -0
  826. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_public_api_discovery.py +0 -0
  827. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_record_schema_coverage.py +0 -0
  828. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_runner.py +0 -0
  829. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_runner_errors.py +0 -0
  830. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/test_spark_testing.py +0 -0
  831. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/testing/__init__.py +0 -0
  832. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/testing/test_runners.py +0 -0
  833. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/testing/test_scenario_and_stubs.py +0 -0
  834. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/etl/testing/test_spark_helpers.py +0 -0
  835. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/__init__.py +0 -0
  836. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_backfill_flow.py +0 -0
  837. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_config.py +0 -0
  838. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_ctx.py +0 -0
  839. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_etl_flow.py +0 -0
  840. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_logging_bridge.py +0 -0
  841. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_maintenance_flow.py +0 -0
  842. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_manifest.py +0 -0
  843. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_manifest_s3.py +0 -0
  844. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_notify.py +0 -0
  845. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_observer.py +0 -0
  846. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_placeholders.py +0 -0
  847. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_task_run_observer.py +0 -0
  848. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prefect/test_yaml_loader.py +0 -0
  849. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prometheus/__init__.py +0 -0
  850. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prometheus/test_adapter.py +0 -0
  851. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/prometheus/test_middleware.py +0 -0
  852. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/release/test_checkout_merged_release.py +0 -0
  853. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/release/test_release_workflow_contract.py +0 -0
  854. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/__init__.py +0 -0
  855. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/_fixture_app.py +0 -0
  856. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_auth_middleware.py +0 -0
  857. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_autocrud.py +0 -0
  858. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_cors.py +0 -0
  859. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_fastapi_auto_logger.py +0 -0
  860. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_fastapi_auto_persistence.py +0 -0
  861. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_middleware.py +0 -0
  862. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
  863. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_request_hardening.py +0 -0
  864. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_response.py +0 -0
  865. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_rest_adapter.py +0 -0
  866. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_rest_compiler.py +0 -0
  867. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_rest_model.py +0 -0
  868. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_route_rbac.py +0 -0
  869. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_router_identity.py +0 -0
  870. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_router_runtime.py +0 -0
  871. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_sql_endpoint.py +0 -0
  872. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/rest/test_sql_serialization.py +0 -0
  873. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/__init__.py +0 -0
  874. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/__init__.py +0 -0
  875. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/cases.py +0 -0
  876. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/conftest.py +0 -0
  877. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_adapter.py +0 -0
  878. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_batch_key.py +0 -0
  879. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_bytewax_dispatcher.py +0 -0
  880. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_collect_batch.py +0 -0
  881. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_dlq.py +0 -0
  882. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_error_boundary.py +0 -0
  883. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_operators.py +0 -0
  884. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_resource_manager.py +0 -0
  885. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_runner.py +0 -0
  886. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_runtime_io.py +0 -0
  887. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_runtime_sink.py +0 -0
  888. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_runtime_source.py +0 -0
  889. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_sink_registry.py +0 -0
  890. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_steps.py +0 -0
  891. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/bytewax/test_storage.py +0 -0
  892. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/__init__.py +0 -0
  893. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/cases.py +0 -0
  894. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/test_async_walk.py +0 -0
  895. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/test_basics.py +0 -0
  896. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/test_config_bindings.py +0 -0
  897. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/test_mongo_source.py +0 -0
  898. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/test_multi_source.py +0 -0
  899. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/test_router.py +0 -0
  900. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/test_window.py +0 -0
  901. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/compiler/test_with.py +0 -0
  902. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/conftest.py +0 -0
  903. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/contracts/__init__.py +0 -0
  904. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/contracts/cases.py +0 -0
  905. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/contracts/test_boundary.py +0 -0
  906. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/contracts/test_message.py +0 -0
  907. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/contracts/test_mongo_contracts.py +0 -0
  908. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/contracts/test_multi_boundary.py +0 -0
  909. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/contracts/test_steps.py +0 -0
  910. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/__init__.py +0 -0
  911. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/cases/__init__.py +0 -0
  912. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/cases/batch.py +0 -0
  913. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/cases/explode.py +0 -0
  914. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/cases/fork.py +0 -0
  915. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/cases/router.py +0 -0
  916. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/cases/shared.py +0 -0
  917. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/cases/simple.py +0 -0
  918. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/conftest.py +0 -0
  919. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/test_compiler_examples.py +0 -0
  920. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/flows/test_flow_examples.py +0 -0
  921. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/__init__.py +0 -0
  922. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/cases.py +0 -0
  923. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/conftest.py +0 -0
  924. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/fakes.py +0 -0
  925. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_client.py +0 -0
  926. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_config.py +0 -0
  927. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_key_resolver.py +0 -0
  928. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_message.py +0 -0
  929. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_message_client.py +0 -0
  930. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_multi_wire.py +0 -0
  931. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_observability.py +0 -0
  932. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_settings.py +0 -0
  933. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/kafka/test_wire.py +0 -0
  934. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/mongo/test_bytewax_source.py +0 -0
  935. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/nodes/__init__.py +0 -0
  936. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/nodes/conftest.py +0 -0
  937. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/nodes/test_broadcast.py +0 -0
  938. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/nodes/test_delta_config.py +0 -0
  939. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/nodes/test_logging.py +0 -0
  940. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/nodes/test_table_package.py +0 -0
  941. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/observability/__init__.py +0 -0
  942. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/observability/cases.py +0 -0
  943. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/observability/conftest.py +0 -0
  944. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/observability/test_observability_runner.py +0 -0
  945. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/observability/test_protocols.py +0 -0
  946. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/observability/test_registry.py +0 -0
  947. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/observability/test_structlog.py +0 -0
  948. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/support/__init__.py +0 -0
  949. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/support/flow_cases.py +0 -0
  950. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/test_expand_routes.py +0 -0
  951. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/test_fork.py +0 -0
  952. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/test_otel_observability.py +0 -0
  953. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/test_routing.py +0 -0
  954. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/test_testing_mongo.py +0 -0
  955. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/streaming/test_with.py +0 -0
  956. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/testing/__init__.py +0 -0
  957. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/testing/test_golden.py +0 -0
  958. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/testing/test_http_harness.py +0 -0
  959. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/testing/test_identity_harness.py +0 -0
  960. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/testing/test_in_memory.py +0 -0
  961. {loom_kernel-0.18.2 → loom_kernel-1.0.0}/tests/unit/testing/test_runner.py +0 -0
@@ -1,3 +1,32 @@
1
+ # 🚀 Release 1.0.0 ([#106](https://github.com/the-reacher-data/loom-py/pull/106)) ([`f8fe343`](https://github.com/the-reacher-data/loom-py/commit/f8fe3433a841711f2393c0def0c1796c1f3b05d8))
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+ ## 🔖 Other
13
+ - and* signs. Public keys stay inline -- they only verify.<br>
14
+ > The signing key is probed once at construction, so a malformed PEM or a key that
15
+ > cannot serve the configured algorithm fails startup. Reading the key is not
16
+ > parsing it: `cryptography` raises a plain `ValueError`, which is neither a
17
+ > `PyJWTError` nor what the port documents `ValueError` to mean, so without the
18
+ > probe a broken deployment surfaced at the first login disguised as a bad login.
19
+ > Verification accepts a map of public keys selected by the token's `kid`, so a
20
+ > key can be rotated with an overlap window instead of a restart that invalidates
21
+ > every live token. The key is chosen by `kid` and never by trying each in turn:
22
+ > exhaustive trial would decouple every algorithm from its key family, which is
23
+ > what keeps algorithm confusion impossible.
24
+ > BREAKING CHANGE: `JwtAuthConfig.public_key: str` is now
25
+ > `public_keys: dict[str, str]`, keyed by `kid`; `JwtAuthConfig.secret: str` is
26
+ > now `secret_path: str`, the path of a file holding the secret; and
27
+ > `verification_key` is a method taking a `kid` instead of a property. Config
28
+
29
+
1
30
  # 🚀 Release 0.18.2 ([#105](https://github.com/the-reacher-data/loom-py/pull/105)) ([`833a45d`](https://github.com/the-reacher-data/loom-py/commit/833a45db6cb8f2870f131eb54a80b12fbf06dd30))
2
31
 
3
32
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loom-kernel
3
- Version: 0.18.2
3
+ Version: 1.0.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Classifier: Typing :: Typed
@@ -148,7 +148,7 @@ app:
148
148
  rest:
149
149
  auth:
150
150
  jwt:
151
- secret: ${oc.env:LOOM_JWT_SECRET}
151
+ secret_path: ${oc.env:LOOM_JWT_SECRET_PATH}
152
152
  algorithms: [HS256]
153
153
  audience: loom-api
154
154
  roles_claim: loom_roles
@@ -447,8 +447,9 @@ app:
447
447
  rest:
448
448
  auth:
449
449
  jwt:
450
- secret: ${oc.env:LOOM_JWT_SECRET} # HS256 — mutually exclusive with public_key
451
- # public_key: ${oc.env:LOOM_JWT_PUBLIC_KEY_PEM} # RS256/ES256 static PEM
450
+ secret_path: ${oc.env:LOOM_JWT_SECRET_PATH} # HS256 — a path, not the value
451
+ # public_keys: # RS256/ES256/EdDSA — one PEM per key id
452
+ # "2026-08": ${oc.env:LOOM_JWT_PUBLIC_KEY_PEM}
452
453
  algorithms: [HS256] # explicit allowlist; 'none' always rejected
453
454
  audience: loom-api # REQUIRED by any sql_endpoint with auth: identity
454
455
  issuer: null # validated only when set
@@ -463,8 +464,21 @@ app:
463
464
  needed; early token revocation is out of scope.
464
465
  - **`sub` is mandatory.** A token without a subject carries no identity to authorize
465
466
  against, nor to audit afterwards, so it is rejected with 401.
466
- - Exactly one of `secret` (HS*) or `public_key` (RS*/ES* static PEM) must be set, and
467
- the algorithm allowlist must match the key type — validated fail-fast at startup.
467
+ - Exactly one of `secret_path` (HS*) or `public_keys` (RS*/ES*/EdDSA static PEMs, keyed by
468
+ key id) must be set, and the algorithm allowlist must match the key type — validated
469
+ fail-fast at startup.
470
+ - **`secret_path` is a path, not the value.** The config is a `msgspec.Struct`, so any
471
+ serializer emits its fields verbatim: holding an HS secret would let a config dump
472
+ publish the key that both verifies *and* signs. Public keys are safe to inline
473
+ because they only verify. The container has to materialize the value to a file:
474
+ Kubernetes mounts a `Secret` as a volume directly, while ECS/Fargate injects
475
+ task-definition secrets as **environment variables only**, so there an entrypoint
476
+ must write the value to a path on a `tmpfs` volume before the app starts.
477
+ - With `public_keys`, the key is chosen by the token's `kid` header, never by trying
478
+ each key in turn: exhaustive trial would decouple every algorithm from its key
479
+ family, which is what makes algorithm confusion impossible here. A token with no
480
+ `kid` verifies only when a single key is configured, so a rotation overlap needs the
481
+ issuer to stamp one.
468
482
  - On success the verified claims are projected onto an
469
483
  {class}`~loom.core.identity.Identity` published for the request; on failure
470
484
  the response is a 401 with the standard error body, a `WWW-Authenticate` challenge
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "loom-kernel"
3
- version = "0.18.2"
3
+ version = "1.0.0"
4
4
  description = "Loom Python project"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -132,7 +132,7 @@ dev = [
132
132
  "pyright>=1.1.390,<2.0",
133
133
  "pytest>=8.3.0",
134
134
  "pytest-asyncio>=0.24.0",
135
- "pyjwt>=2.12.0",
135
+ "pyjwt[crypto]>=2.12.0",
136
136
  "redis>=5.0.0",
137
137
  "ruff>=0.9.0,<1.0",
138
138
  "sqlalchemy>=2.0,<3.0",
@@ -278,7 +278,7 @@ markers = [
278
278
 
279
279
  [tool.commitizen]
280
280
  name = "cz_conventional_commits"
281
- version = "0.18.2"
281
+ version = "1.0.0"
282
282
  tag_format = "v$version"
283
283
  version_files = [
284
284
  "pyproject.toml:project.version",
@@ -8,10 +8,13 @@ no transport and no infrastructure.
8
8
 
9
9
  from loom.core.identity.context import current_identity, reset_identity, set_identity
10
10
  from loom.core.identity.identity import ANONYMOUS, Identity
11
+ from loom.core.identity.issuer import IssuedToken, TokenIssuer
11
12
 
12
13
  __all__ = [
13
14
  "ANONYMOUS",
14
15
  "Identity",
16
+ "IssuedToken",
17
+ "TokenIssuer",
15
18
  "current_identity",
16
19
  "reset_identity",
17
20
  "set_identity",
@@ -0,0 +1,70 @@
1
+ """Minting a credential for a verified :class:`Identity`.
2
+
3
+ The port lives beside the identity it consumes, not beside the transport that
4
+ implements it: the caller is a login use case, so putting the abstraction in
5
+ ``loom.rest`` would make the application layer import infrastructure. What is
6
+ domain here is *"this service needs to mint a credential for this identity"*;
7
+ that a JWT comes out is the detail, and it belongs to the implementation.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from dataclasses import dataclass
13
+ from datetime import datetime, timedelta
14
+ from typing import Protocol
15
+
16
+ from loom.core.identity.identity import Identity
17
+
18
+
19
+ @dataclass(frozen=True, slots=True)
20
+ class IssuedToken:
21
+ """A minted credential together with what the issuer already knew about it.
22
+
23
+ Returned instead of a bare string so a login endpoint never has to decode
24
+ the token it just signed: the expiry the HTTP response advertises and the
25
+ identifier the audit trail records are both produced by the signing step.
26
+
27
+ Attributes:
28
+ token: The encoded credential, ready to travel as a bearer token.
29
+ expires_at: Instant the credential stops being valid, timezone-aware.
30
+ jti: Unique identifier of this minting, for correlation and audit.
31
+ """
32
+
33
+ token: str
34
+ expires_at: datetime
35
+ jti: str
36
+
37
+
38
+ class TokenIssuer(Protocol):
39
+ """Mints a credential that an :class:`Authenticator` can later verify.
40
+
41
+ Implementations guarantee the round trip: whatever the identity carries —
42
+ subject, roles and attributes — a matching authenticator recovers intact.
43
+ Everything the credential says comes from the identity, so no caller can
44
+ smuggle a claim past it.
45
+
46
+ Example::
47
+
48
+ issued = issuer.issue(identity)
49
+ response = {"access_token": issued.token, "expires_at": issued.expires_at}
50
+ """
51
+
52
+ def issue(self, identity: Identity, *, ttl: timedelta | None = None) -> IssuedToken:
53
+ """Mint a credential for *identity*.
54
+
55
+ Args:
56
+ identity: Verified caller the credential speaks for.
57
+ ttl: Lifetime override. ``None`` uses the configured one, which is
58
+ also the ceiling: a longer lifetime is refused.
59
+
60
+ Returns:
61
+ The minted credential and its metadata.
62
+
63
+ Raises:
64
+ ValueError: If the identity cannot be represented — anonymous, or
65
+ carrying an attribute that would be unreadable once encoded —
66
+ or if *ttl* exceeds the configured lifetime.
67
+ RuntimeError: If the credential cannot be produced. Implementations
68
+ keep the cause out of the traceback: it can carry key material.
69
+ """
70
+ ...
@@ -13,8 +13,8 @@ Install the optional JWT dependency with::
13
13
  """
14
14
 
15
15
  from loom.rest.auth.abc import Authenticator, RequestCredentials
16
- from loom.rest.auth.config import JwtAuthConfig
17
- from loom.rest.auth.jwt import JwtAuthenticator
16
+ from loom.rest.auth.config import JwtAuthConfig, JwtIssuerConfig
17
+ from loom.rest.auth.jwt import JwtAuthenticator, JwtIssuer
18
18
  from loom.rest.auth.middleware import AuthenticationMiddleware, JwtAuthMiddleware
19
19
 
20
20
  __all__ = [
@@ -23,5 +23,7 @@ __all__ = [
23
23
  "JwtAuthConfig",
24
24
  "JwtAuthMiddleware",
25
25
  "JwtAuthenticator",
26
+ "JwtIssuer",
27
+ "JwtIssuerConfig",
26
28
  "RequestCredentials",
27
29
  ]
@@ -0,0 +1,317 @@
1
+ """Configuration for the native stateless JWT authentication middleware."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ from loom.core.config.errors import ConfigError
8
+ from loom.core.model import LoomFrozenStruct
9
+
10
+ DEFAULT_EXCLUDE_PATHS: tuple[str, ...] = ("/docs", "/redoc", "/openapi.json", "/metrics")
11
+ """Paths served without authentication unless the application says otherwise."""
12
+
13
+ _FORBIDDEN_ALGORITHM = "none"
14
+
15
+ MAX_ISSUER_TTL_SECONDS = 3600
16
+ """Ceiling for a minted token: signing is reading, so a long-lived token is a
17
+ standing grant that stateless verification cannot revoke."""
18
+
19
+ SUPPORTED_ALGORITHMS: frozenset[str] = frozenset(
20
+ {
21
+ "EdDSA",
22
+ "ES256",
23
+ "ES384",
24
+ "ES512",
25
+ "HS256",
26
+ "HS384",
27
+ "HS512",
28
+ "PS256",
29
+ "PS384",
30
+ "PS512",
31
+ "RS256",
32
+ "RS384",
33
+ "RS512",
34
+ }
35
+ )
36
+ """Algorithms this framework signs with, checked at startup rather than on the
37
+ first request: a typo like ``" HS256"`` would otherwise fail per-call."""
38
+
39
+
40
+ # RFC 7519 registered claims: a roles claim named after one of these is silently
41
+ # overwritten when the token is built, leaving no roles and no error.
42
+ RESERVED_CLAIMS: frozenset[str] = frozenset({"iss", "sub", "aud", "exp", "nbf", "iat", "jti"})
43
+
44
+
45
+ def _is_symmetric(algorithm: str) -> bool:
46
+ """Return ``True`` when *algorithm* uses a shared secret (HS* family)."""
47
+ return algorithm.upper().startswith("HS")
48
+
49
+
50
+ def _require_supported(algorithm: str, *, setting: str) -> None:
51
+ """Reject ``none`` and anything outside the supported set, at startup.
52
+
53
+ Shared by both configs on purpose: a hardening applied to one and not the
54
+ other is how the two drift apart.
55
+ """
56
+ if algorithm.lower() == _FORBIDDEN_ALGORITHM:
57
+ raise ConfigError("The 'none' JWT algorithm is always forbidden.")
58
+ if algorithm not in SUPPORTED_ALGORITHMS:
59
+ raise ConfigError(
60
+ f"{setting} {algorithm!r} is not supported. "
61
+ f"Choose one of: {', '.join(sorted(SUPPORTED_ALGORITHMS))}."
62
+ )
63
+
64
+
65
+ def _read_key_file(path: str, *, setting: str) -> str:
66
+ """Read key material from disk, never chaining the cause.
67
+
68
+ An ``OSError`` message carries the path and a ``UnicodeDecodeError`` carries
69
+ the whole file on ``exc.object``: either would publish key material through a
70
+ traceback or a structured log that serializes the exception.
71
+ """
72
+ try:
73
+ return Path(path).read_text(encoding="utf-8")
74
+ except (OSError, UnicodeDecodeError):
75
+ raise ConfigError(f"Could not read {setting}.") from None
76
+
77
+
78
+ def _require_usable_roles_claim(roles_claim: str) -> None:
79
+ """Reject a roles claim that is blank or shadows a registered claim."""
80
+ if not roles_claim or not roles_claim.strip():
81
+ raise ConfigError("JWT issuer requires a non-blank 'roles_claim'.")
82
+ if roles_claim in RESERVED_CLAIMS:
83
+ raise ConfigError(
84
+ f"JWT issuer 'roles_claim' {roles_claim!r} is a registered claim: "
85
+ "the token would carry no roles and raise nothing."
86
+ )
87
+
88
+
89
+ class JwtAuthConfig(LoomFrozenStruct, frozen=True, kw_only=True):
90
+ """Validated settings for :class:`~loom.rest.auth.JwtAuthMiddleware`.
91
+
92
+ Binds from the ``app.rest.auth.jwt`` config section. Validation runs on
93
+ construction (fail-fast): exactly one key source must be provided and the
94
+ algorithm allowlist must be non-empty and coherent with that key source.
95
+
96
+ Attributes:
97
+ secret_path: Filesystem path of the shared secret for symmetric
98
+ algorithms (HS*). A path and not the value: this is a
99
+ ``msgspec.Struct``, so any serializer emits its fields verbatim and a
100
+ config dump would publish the key that verifies *and signs*.
101
+ Mutually exclusive with ``public_keys``.
102
+ public_keys: Static PEM-encoded public keys for asymmetric algorithms
103
+ (RS*/ES*/EdDSA), keyed by the ``kid`` that selects them. Mutually
104
+ exclusive with ``secret``.
105
+ algorithms: Explicit allowlist of accepted JWT algorithms. The
106
+ ``none`` algorithm is always forbidden.
107
+ audience: Expected ``aud`` claim. Validated only when set.
108
+ issuer: Expected ``iss`` claim. Validated only when set.
109
+ leeway_seconds: Clock-skew tolerance applied to time-based claims.
110
+ exclude_paths: Exact request paths that bypass authentication.
111
+ roles_claim: Name of the verified claim carrying the roles the caller
112
+ is authorized to use. Consumed by the SQL endpoint: the effective
113
+ roles are the claim values intersected with the connection
114
+ allowlist, and the request body can only narrow that set.
115
+
116
+ Raises:
117
+ ConfigError: If key sources, algorithms, leeway, or the roles claim
118
+ name are invalid.
119
+
120
+ Example YAML::
121
+
122
+ app:
123
+ rest:
124
+ auth:
125
+ jwt:
126
+ secret_path: ${oc.env:LOOM_JWT_SECRET_PATH}
127
+ algorithms: [HS256]
128
+ roles_claim: loom_sql_roles
129
+ """
130
+
131
+ secret_path: str | None = None
132
+ public_keys: dict[str, str] = {}
133
+ algorithms: tuple[str, ...] = ()
134
+ audience: str | None = None
135
+ issuer: str | None = None
136
+ leeway_seconds: int = 0
137
+ exclude_paths: tuple[str, ...] = DEFAULT_EXCLUDE_PATHS
138
+ roles_claim: str | None = None
139
+
140
+ def __repr__(self) -> str:
141
+ return (
142
+ f"JwtAuthConfig(secret_path={self.secret_path!r},"
143
+ f" public_keys={sorted(self.public_keys)!r},"
144
+ f" algorithms={self.algorithms!r},"
145
+ f" audience={self.audience!r},"
146
+ f" issuer={self.issuer!r},"
147
+ f" leeway_seconds={self.leeway_seconds!r},"
148
+ f" exclude_paths={self.exclude_paths!r},"
149
+ f" roles_claim={self.roles_claim!r})"
150
+ )
151
+
152
+ def __post_init__(self) -> None:
153
+ if (self.secret_path is None) == (not self.public_keys):
154
+ raise ConfigError("JWT auth requires exactly one of 'secret_path' or 'public_keys'.")
155
+ for key_id, material in self.public_keys.items():
156
+ if not key_id.strip() or not material.strip():
157
+ raise ConfigError("JWT auth 'public_keys' entries need a key id and material.")
158
+ if not self.algorithms:
159
+ raise ConfigError("JWT auth requires a non-empty 'algorithms' allowlist.")
160
+ if self.leeway_seconds < 0:
161
+ raise ConfigError("JWT auth 'leeway_seconds' must be >= 0.")
162
+ if self.roles_claim is not None and not self.roles_claim.strip():
163
+ raise ConfigError("JWT auth 'roles_claim' must not be blank.")
164
+ for algorithm in self.algorithms:
165
+ self._validate_algorithm(algorithm)
166
+
167
+ def _validate_algorithm(self, algorithm: str) -> None:
168
+ _require_supported(algorithm, setting="JWT auth 'algorithms' entry")
169
+ if _is_symmetric(algorithm) and self.secret_path is None:
170
+ raise ConfigError(
171
+ f"JWT algorithm {algorithm!r} requires 'secret_path', not 'public_keys'."
172
+ )
173
+ if not _is_symmetric(algorithm) and not self.public_keys:
174
+ raise ConfigError(f"JWT algorithm {algorithm!r} requires 'public_keys', not 'secret'.")
175
+
176
+ def verification_key(self, key_id: str | None) -> str | None:
177
+ """Return the key that verifies a token, selected by its ``kid``.
178
+
179
+ Selection is explicit and never exhaustive: trying every configured key
180
+ in turn would decouple each algorithm from its key family, which is what
181
+ makes algorithm confusion structurally impossible here.
182
+
183
+ Args:
184
+ key_id: ``kid`` header of the token, or ``None`` when it carries none.
185
+
186
+ Returns:
187
+ The key material, or ``None`` when no configured key applies — an
188
+ unknown ``kid``, or a missing one while several keys are configured.
189
+ """
190
+ if self.secret_path is not None:
191
+ return _read_key_file(self.secret_path, setting="JWT auth 'secret_path'")
192
+ if key_id is not None:
193
+ return self.public_keys.get(key_id)
194
+ if len(self.public_keys) == 1:
195
+ return next(iter(self.public_keys.values()))
196
+ return None
197
+
198
+
199
+ class JwtIssuerConfig(LoomFrozenStruct, frozen=True, kw_only=True):
200
+ """Validated settings for :class:`~loom.rest.auth.JwtIssuer`.
201
+
202
+ Separate from :class:`JwtAuthConfig` on purpose, and not a few extra fields
203
+ on it: a service that only verifies must have no configuration path through
204
+ which signing material can land in its process. The fields diverge anyway —
205
+ one algorithm instead of an allowlist, ``audience`` and ``issuer`` mandatory
206
+ rather than optional, a lifetime the verifier has no use for.
207
+
208
+ The private key is read from ``private_key_path`` and never held as a field.
209
+ ``__repr__`` redaction would not be enough: this is a ``msgspec.Struct``, so
210
+ ``msgspec.json.encode`` and ``to_builtins`` emit every field verbatim without
211
+ going through it, and a config dump would publish the signing key.
212
+
213
+ Attributes:
214
+ private_key_path: Filesystem path of the PEM signing key, for
215
+ asymmetric algorithms. Mutually exclusive with ``secret``.
216
+ secret_path: Filesystem path of the shared secret for HS* algorithms.
217
+ Requires ``allow_symmetric_signing``. Mutually exclusive with
218
+ ``private_key_path``.
219
+ algorithm: The single algorithm tokens are signed with. Issuing chooses
220
+ one; only verification negotiates an allowlist.
221
+ audience: ``aud`` stamped on every token. Mandatory: a token without an
222
+ audience is valid at any service that shares the key.
223
+ issuer: ``iss`` stamped on every token. Mandatory.
224
+ roles_claim: Claim carrying the caller roles. Mandatory, and never a
225
+ registered claim: an issuer that does not own that name lets an
226
+ attribute impersonate it. An identity without roles is refused.
227
+ ttl_seconds: Lifetime of a minted token, in ``1..MAX_ISSUER_TTL_SECONDS``,
228
+ and the ceiling for any per-call override.
229
+ kid: Key identifier stamped on the token header, so a verifier can
230
+ select the right key during a rotation overlap.
231
+ allow_symmetric_signing: Opt-in required for HS*. With a shared secret
232
+ every verifier can also mint, so the choice must be deliberate.
233
+
234
+ Raises:
235
+ ConfigError: If key sources, algorithm, audience, issuer, roles claim
236
+ or lifetime are invalid.
237
+
238
+ Note:
239
+ Built programmatically, not bound from a config section: issuing happens in
240
+ an application use case that injects the issuer, not in the REST layer that
241
+ owns ``app.rest.auth``. Resolve the values however the service resolves its
242
+ own settings.
243
+
244
+ Example::
245
+
246
+ config = JwtIssuerConfig(
247
+ private_key_path=os.environ["JWT_SIGNING_KEY_PATH"],
248
+ algorithm="EdDSA",
249
+ audience="my-api",
250
+ issuer="my-gateway",
251
+ roles_claim="loom_sql_roles",
252
+ ttl_seconds=900,
253
+ kid="2026-08",
254
+ )
255
+ """
256
+
257
+ private_key_path: str | None = None
258
+ secret_path: str | None = None
259
+ algorithm: str = ""
260
+ audience: str = ""
261
+ issuer: str = ""
262
+ roles_claim: str = ""
263
+ ttl_seconds: int = 900
264
+ kid: str | None = None
265
+ allow_symmetric_signing: bool = False
266
+
267
+ def __post_init__(self) -> None:
268
+ if (self.private_key_path is None) == (self.secret_path is None):
269
+ raise ConfigError(
270
+ "JWT issuer requires exactly one of 'private_key_path' or 'secret_path'."
271
+ )
272
+ _require_supported(self.algorithm, setting="JWT issuer 'algorithm'")
273
+ if not self.audience.strip():
274
+ raise ConfigError("JWT issuer requires a non-blank 'audience'.")
275
+ if not self.issuer.strip():
276
+ raise ConfigError("JWT issuer requires a non-blank 'issuer'.")
277
+ # Optional here is what let an attribute impersonate the verifier's roles
278
+ # claim: the issuer must always own that name.
279
+ _require_usable_roles_claim(self.roles_claim)
280
+ if self.kid is not None and not self.kid.strip():
281
+ raise ConfigError("JWT issuer 'kid' must not be blank.")
282
+ if not 0 < self.ttl_seconds <= MAX_ISSUER_TTL_SECONDS:
283
+ raise ConfigError(f"JWT issuer 'ttl_seconds' must be in 1..{MAX_ISSUER_TTL_SECONDS}.")
284
+ self._validate_signing_material()
285
+
286
+ def _validate_signing_material(self) -> None:
287
+ symmetric = _is_symmetric(self.algorithm)
288
+ if symmetric and not self.allow_symmetric_signing:
289
+ raise ConfigError(
290
+ f"JWT algorithm {self.algorithm!r} shares one key between signer and "
291
+ "verifier, so every verifier could also mint. Set "
292
+ "'allow_symmetric_signing' to accept that."
293
+ )
294
+ if symmetric and self.secret_path is None:
295
+ raise ConfigError(
296
+ f"JWT algorithm {self.algorithm!r} requires 'secret_path', not 'private_key_path'."
297
+ )
298
+ if not symmetric and self.private_key_path is None:
299
+ raise ConfigError(
300
+ f"JWT algorithm {self.algorithm!r} requires 'private_key_path', not 'secret_path'."
301
+ )
302
+
303
+ def load_signing_key(self) -> str:
304
+ """Read the signing key, so it lives in the issuer and not in the config.
305
+
306
+ Returns:
307
+ The key material read from disk.
308
+
309
+ Raises:
310
+ ConfigError: If the file cannot be read or is not UTF-8 text. The
311
+ cause is never chained: an OS error carries the path, and a
312
+ ``UnicodeDecodeError`` carries the file contents on ``exc.object``.
313
+ """
314
+ source = self.secret_path or self.private_key_path
315
+ if source is None: # pragma: no cover - __post_init__ rules this out
316
+ raise ConfigError("JWT issuer has no signing key configured.")
317
+ return _read_key_file(source, setting="the JWT issuer signing key")