loom-kernel 2.12.0__tar.gz → 2.14.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 (666) hide show
  1. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/CHANGELOG.md +90 -0
  2. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/PKG-INFO +1 -1
  3. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/bootstrap.py +35 -5
  4. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/scoped_ddl.py +57 -1
  5. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/sqlalchemy.py +191 -24
  6. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/bootstrap/bootstrap.py +3 -1
  7. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/gateway.py +51 -24
  8. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/errors/codes.py +1 -0
  9. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/locator.py +15 -3
  10. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/__init__.py +14 -0
  11. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/convert.py +12 -1
  12. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/introspection.py +159 -4
  13. loom_kernel-2.14.0/src/loom/core/model/partition.py +114 -0
  14. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/scoped.py +21 -1
  15. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/types.py +1 -0
  16. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/types_postgres.py +1 -0
  17. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/backend.py +17 -6
  18. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +19 -5
  19. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +182 -4
  20. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +22 -5
  21. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/mixins.py +1 -1
  22. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +6 -0
  23. loom_kernel-2.14.0/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +68 -0
  24. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +16 -0
  25. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +25 -7
  26. loom_kernel-2.14.0/src/loom/core/repository/sqlalchemy/rls/partitions.py +196 -0
  27. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +24 -5
  28. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/schema_names.py +23 -0
  29. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/__init__.py +2 -1
  30. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/abc.py +39 -0
  31. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/middleware.py +46 -7
  32. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/errors.py +22 -16
  33. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/_errors.py +1 -1
  34. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/auto.py +26 -1
  35. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/.gitignore +0 -0
  36. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/LICENSE +0 -0
  37. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/README.md +0 -0
  38. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/pyproject.toml +0 -0
  39. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/__init__.py +0 -0
  40. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/__init__.py +0 -0
  41. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_concurrency.py +0 -0
  42. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_filters.py +0 -0
  43. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_roles.py +0 -0
  44. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_startup.py +0 -0
  45. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_transport.py +0 -0
  46. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_usecase.py +0 -0
  47. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/__init__.py +0 -0
  48. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/_binding.py +0 -0
  49. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/_handlers.py +0 -0
  50. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/_rpc.py +0 -0
  51. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/card.py +0 -0
  52. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/events.py +0 -0
  53. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/server.py +0 -0
  54. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/abc.py +0 -0
  55. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/__init__.py +0 -0
  56. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/_compiler.py +0 -0
  57. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/_plan.py +0 -0
  58. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
  59. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
  60. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
  61. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
  62. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
  63. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
  64. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
  65. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
  66. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_output.py +0 -0
  67. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_state.py +0 -0
  68. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/config.py +0 -0
  69. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/__init__.py +0 -0
  70. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/_envelope.py +0 -0
  71. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/_schema.py +0 -0
  72. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/_v1.py +0 -0
  73. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
  74. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/describe.py +0 -0
  75. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/__init__.py +0 -0
  76. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
  77. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
  78. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
  79. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
  80. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
  81. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
  82. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
  83. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
  84. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
  85. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
  86. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
  87. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
  88. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
  89. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
  90. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
  91. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
  92. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
  93. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
  94. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
  95. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
  96. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
  97. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
  98. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
  99. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
  100. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
  101. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
  102. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
  103. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
  104. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
  105. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
  106. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
  107. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/errors.py +0 -0
  108. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/fastapi/__init__.py +0 -0
  109. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/fastapi/endpoints.py +0 -0
  110. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/fastapi/response.py +0 -0
  111. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/fastapi/streaming.py +0 -0
  112. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/inference.py +0 -0
  113. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/registry.py +0 -0
  114. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/remote_auth.py +0 -0
  115. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/__init__.py +0 -0
  116. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_bounded.py +0 -0
  117. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_chain.py +0 -0
  118. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_conversation.py +0 -0
  119. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_grants.py +0 -0
  120. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_handle.py +0 -0
  121. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_health.py +0 -0
  122. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_hooks.py +0 -0
  123. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
  124. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_limits.py +0 -0
  125. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_mcp.py +0 -0
  126. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/validate/__init__.py +0 -0
  127. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/validate/__main__.py +0 -0
  128. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/__init__.py +0 -0
  129. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/auto.py +0 -0
  130. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/config.py +0 -0
  131. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/constants.py +0 -0
  132. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/runner.py +0 -0
  133. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/service.py +0 -0
  134. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/cli/__init__.py +0 -0
  135. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/cli/app.py +0 -0
  136. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/cli/schema.py +0 -0
  137. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/async_bridge.py +0 -0
  138. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/__init__.py +0 -0
  139. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/_decide.py +0 -0
  140. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/_grants.py +0 -0
  141. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/_roles.py +0 -0
  142. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/_scope.py +0 -0
  143. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/elevation.py +0 -0
  144. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/product.py +0 -0
  145. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/__init__.py +0 -0
  146. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/core_model.py +0 -0
  147. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/protocol.py +0 -0
  148. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/bootstrap/__init__.py +0 -0
  149. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/bootstrap/kernel.py +0 -0
  150. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/__init__.py +0 -0
  151. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/_batching.py +0 -0
  152. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/_single_flight.py +0 -0
  153. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/abc/__init__.py +0 -0
  154. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/abc/backend.py +0 -0
  155. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/abc/config.py +0 -0
  156. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/abc/dependency.py +0 -0
  157. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/calls.py +0 -0
  158. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/codec.py +0 -0
  159. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/decorators.py +0 -0
  160. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/dependency.py +0 -0
  161. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/errors.py +0 -0
  162. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/keys.py +0 -0
  163. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/memory.py +0 -0
  164. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/repository.py +0 -0
  165. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/result_codec.py +0 -0
  166. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/serializer.py +0 -0
  167. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/wiring.py +0 -0
  168. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/__init__.py +0 -0
  169. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/adapter.py +0 -0
  170. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/base.py +0 -0
  171. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/field.py +0 -0
  172. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/introspection.py +0 -0
  173. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/compiler.py +0 -0
  174. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/__init__.py +0 -0
  175. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/_boto3.py +0 -0
  176. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/_includes.py +0 -0
  177. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/_resolver_utils.py +0 -0
  178. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/binder.py +0 -0
  179. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/configurable.py +0 -0
  180. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/context.py +0 -0
  181. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/errors.py +0 -0
  182. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/keys.py +0 -0
  183. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/loader.py +0 -0
  184. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/model.py +0 -0
  185. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/observability.py +0 -0
  186. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/resolver.py +0 -0
  187. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/secrets.py +0 -0
  188. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/ssm.py +0 -0
  189. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/contracts/__init__.py +0 -0
  190. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/contracts/manifest.py +0 -0
  191. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/di/__init__.py +0 -0
  192. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/di/container.py +0 -0
  193. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/di/scope.py +0 -0
  194. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/__init__.py +0 -0
  195. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/_utils.py +0 -0
  196. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/base.py +0 -0
  197. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/interfaces.py +0 -0
  198. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/manifest.py +0 -0
  199. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/modules.py +0 -0
  200. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/__init__.py +0 -0
  201. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/compilable.py +0 -0
  202. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/compiler.py +0 -0
  203. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/events.py +0 -0
  204. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/executor.py +0 -0
  205. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/metrics.py +0 -0
  206. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/plan.py +0 -0
  207. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/post_commit.py +0 -0
  208. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/errors/__init__.py +0 -0
  209. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/errors/errors.py +0 -0
  210. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/expr/__init__.py +0 -0
  211. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/expr/eval.py +0 -0
  212. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/expr/nodes.py +0 -0
  213. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/expr/refs.py +0 -0
  214. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/__init__.py +0 -0
  215. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/context.py +0 -0
  216. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/identity.py +0 -0
  217. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/issuer.py +0 -0
  218. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/wire.py +0 -0
  219. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/introspection/__init__.py +0 -0
  220. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/introspection/base.py +0 -0
  221. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/introspection/describe.py +0 -0
  222. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/__init__.py +0 -0
  223. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/callback.py +0 -0
  224. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/context.py +0 -0
  225. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/handle.py +0 -0
  226. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/job.py +0 -0
  227. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/service.py +0 -0
  228. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/__init__.py +0 -0
  229. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/abc.py +0 -0
  230. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/config.py +0 -0
  231. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/registry.py +0 -0
  232. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/structlogger.py +0 -0
  233. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/_loom_type.py +0 -0
  234. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/base.py +0 -0
  235. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/enums.py +0 -0
  236. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/field.py +0 -0
  237. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/privilege.py +0 -0
  238. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/projection.py +0 -0
  239. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/relation.py +0 -0
  240. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/struct.py +0 -0
  241. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/timestamped.py +0 -0
  242. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/__init__.py +0 -0
  243. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/config.py +0 -0
  244. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/event.py +0 -0
  245. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/observer/__init__.py +0 -0
  246. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/observer/noop.py +0 -0
  247. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/observer/otel.py +0 -0
  248. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/observer/structlog.py +0 -0
  249. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/otel_ids.py +0 -0
  250. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/protocol.py +0 -0
  251. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/runtime.py +0 -0
  252. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/span.py +0 -0
  253. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/topology.py +0 -0
  254. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/persistence/__init__.py +0 -0
  255. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/persistence/abc.py +0 -0
  256. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/persistence/none.py +0 -0
  257. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/persistence/registry.py +0 -0
  258. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/plugins/__init__.py +0 -0
  259. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/plugins/entrypoints.py +0 -0
  260. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/plugins/optional.py +0 -0
  261. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/projection/__init__.py +0 -0
  262. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/projection/loaders.py +0 -0
  263. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/projection/runtime.py +0 -0
  264. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/__init__.py +0 -0
  265. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/__init__.py +0 -0
  266. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/cursor.py +0 -0
  267. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/errors.py +0 -0
  268. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/query.py +0 -0
  269. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
  270. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  271. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/repository.py +0 -0
  272. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/session_scope.py +0 -0
  273. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
  274. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/backend.py +0 -0
  275. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
  276. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
  277. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
  278. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/__init__.py +0 -0
  279. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/backend.py +0 -0
  280. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/ids.py +0 -0
  281. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
  282. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/registry.py +0 -0
  283. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/repository.py +0 -0
  284. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/uow.py +0 -0
  285. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/values.py +0 -0
  286. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mutation.py +0 -0
  287. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/registration.py +0 -0
  288. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/registry.py +0 -0
  289. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  290. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  291. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  292. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
  293. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
  294. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  295. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  296. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  297. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  298. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  299. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  300. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  301. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
  302. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  303. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  304. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  305. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  306. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  307. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
  308. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
  309. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
  310. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
  311. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
  312. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
  313. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
  314. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
  315. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
  316. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
  317. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  318. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  319. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/response/__init__.py +0 -0
  320. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/response/base.py +0 -0
  321. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/routing/__init__.py +0 -0
  322. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/routing/ref.py +0 -0
  323. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/routing/resolver.py +0 -0
  324. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/runner.py +0 -0
  325. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/schema/__init__.py +0 -0
  326. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/schema/schema_mode.py +0 -0
  327. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/__init__.py +0 -0
  328. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/abc/__init__.py +0 -0
  329. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/abc/contracts.py +0 -0
  330. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/abc/errors.py +0 -0
  331. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/caller_bound.py +0 -0
  332. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
  333. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
  334. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
  335. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
  336. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/config.py +0 -0
  337. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/roles.py +0 -0
  338. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/service.py +0 -0
  339. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/symbols.py +0 -0
  340. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/tracing/__init__.py +0 -0
  341. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/tracing/context.py +0 -0
  342. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/transaction.py +0 -0
  343. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/transport/__init__.py +0 -0
  344. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/transport/adapter.py +0 -0
  345. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/uow/__init__.py +0 -0
  346. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/uow/abc.py +0 -0
  347. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/uow/context.py +0 -0
  348. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/__init__.py +0 -0
  349. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/_predicates.py +0 -0
  350. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/agent_markers.py +0 -0
  351. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/compute.py +0 -0
  352. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/constants.py +0 -0
  353. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/factory.py +0 -0
  354. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/field_ref.py +0 -0
  355. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/invoker.py +0 -0
  356. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/keys.py +0 -0
  357. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/markers.py +0 -0
  358. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/mcp_markers.py +0 -0
  359. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/registry.py +0 -0
  360. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/rule.py +0 -0
  361. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/use_case.py +0 -0
  362. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/__init__.py +0 -0
  363. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/__init__.py +0 -0
  364. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_format_registry.py +0 -0
  365. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
  366. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_common.py +0 -0
  367. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_log.py +0 -0
  368. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
  369. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
  370. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
  371. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_merge.py +0 -0
  372. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_path_template.py +0 -0
  373. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_predicate.py +0 -0
  374. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  375. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  376. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  377. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_write_policy.py +0 -0
  378. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/__init__.py +0 -0
  379. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  380. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  381. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_historify.py +0 -0
  382. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  383. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_reader.py +0 -0
  384. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  385. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  386. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
  387. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_writer.py +0 -0
  388. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/provider.py +0 -0
  389. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  390. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  391. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_historify.py +0 -0
  392. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  393. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  394. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  395. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_writer.py +0 -0
  396. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/provider.py +0 -0
  397. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/__init__.py +0 -0
  398. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
  399. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  400. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
  401. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_options.py +0 -0
  402. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  403. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  404. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_store.py +0 -0
  405. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/__init__.py +0 -0
  406. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_binding.py +0 -0
  407. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_compiler.py +0 -0
  408. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_errors.py +0 -0
  409. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_plan.py +0 -0
  410. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_validators.py +0 -0
  411. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_validators_config.py +0 -0
  412. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  413. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_validators_step.py +0 -0
  414. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/__init__.py +0 -0
  415. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/_format.py +0 -0
  416. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/_read_options.py +0 -0
  417. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/_utils.py +0 -0
  418. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/_write_options.py +0 -0
  419. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  420. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  421. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  422. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  423. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
  424. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/__init__.py +0 -0
  425. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from.py +0 -0
  426. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
  427. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
  428. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
  429. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
  430. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_specs.py +0 -0
  431. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/__init__.py +0 -0
  432. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_client.py +0 -0
  433. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_file.py +0 -0
  434. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
  435. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
  436. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
  437. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
  438. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
  439. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
  440. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_into.py +0 -0
  441. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
  442. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_table.py +0 -0
  443. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  444. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/executor/__init__.py +0 -0
  445. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  446. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/executor/_executor.py +0 -0
  447. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/__init__.py +0 -0
  448. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/_registry.py +0 -0
  449. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/__init__.py +0 -0
  450. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
  451. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
  452. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
  453. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
  454. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_mongo.py +0 -0
  455. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
  456. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
  457. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
  458. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_serialization.py +0 -0
  459. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/targets/__init__.py +0 -0
  460. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
  461. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/__init__.py +0 -0
  462. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/_config.py +0 -0
  463. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/_observer.py +0 -0
  464. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/_records.py +0 -0
  465. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
  466. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
  467. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
  468. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
  469. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/__init__.py +0 -0
  470. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_builder.py +0 -0
  471. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_ops.py +0 -0
  472. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_protocol.py +0 -0
  473. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_runner.py +0 -0
  474. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_step.py +0 -0
  475. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
  476. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
  477. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/__init__.py +0 -0
  478. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_generics.py +0 -0
  479. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_params.py +0 -0
  480. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  481. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_process.py +0 -0
  482. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_sql.py +0 -0
  483. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_step.py +0 -0
  484. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_step_client.py +0 -0
  485. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  486. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/__init__.py +0 -0
  487. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/_providers.py +0 -0
  488. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/_wiring.py +0 -0
  489. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/config_loader.py +0 -0
  490. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/core.py +0 -0
  491. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/errors.py +0 -0
  492. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/filtering.py +0 -0
  493. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runtime/__init__.py +0 -0
  494. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runtime/_config_values.py +0 -0
  495. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runtime/contracts.py +0 -0
  496. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/schema/__init__.py +0 -0
  497. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/schema/_contract.py +0 -0
  498. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/schema/_schema.py +0 -0
  499. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/__init__.py +0 -0
  500. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/_config.py +0 -0
  501. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/_file_locator.py +0 -0
  502. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/_locator.py +0 -0
  503. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/routing.py +0 -0
  504. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/__init__.py +0 -0
  505. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/_result.py +0 -0
  506. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/_runners.py +0 -0
  507. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/_scenario.py +0 -0
  508. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/_stubs.py +0 -0
  509. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/spark.py +0 -0
  510. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/__init__.py +0 -0
  511. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_async.py +0 -0
  512. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_config.py +0 -0
  513. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_ctx.py +0 -0
  514. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_flow_yaml.py +0 -0
  515. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_meta.py +0 -0
  516. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_placeholders.py +0 -0
  517. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_summary.py +0 -0
  518. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/__init__.py +0 -0
  519. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/_discovery.py +0 -0
  520. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/_schedule.py +0 -0
  521. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/_yaml_etls.py +0 -0
  522. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/entrypoint.py +0 -0
  523. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/__init__.py +0 -0
  524. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_assemble.py +0 -0
  525. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_backfill.py +0 -0
  526. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
  527. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_body.py +0 -0
  528. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_common.py +0 -0
  529. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_factory.py +0 -0
  530. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_hooks.py +0 -0
  531. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_maintenance.py +0 -0
  532. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_params.py +0 -0
  533. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_run_name.py +0 -0
  534. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_runtime.py +0 -0
  535. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_signature.py +0 -0
  536. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_stages.py +0 -0
  537. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/manifest/__init__.py +0 -0
  538. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/manifest/_model.py +0 -0
  539. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/manifest/_s3.py +0 -0
  540. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/manifest/_store.py +0 -0
  541. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/__init__.py +0 -0
  542. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/_event.py +0 -0
  543. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/_factory.py +0 -0
  544. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/_port.py +0 -0
  545. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/_slack.py +0 -0
  546. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/__init__.py +0 -0
  547. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/_flow.py +0 -0
  548. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
  549. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/_manifest.py +0 -0
  550. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/_task_run.py +0 -0
  551. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/__init__.py +0 -0
  552. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/_instruments.py +0 -0
  553. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/adapter.py +0 -0
  554. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/kafka.py +0 -0
  555. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/lifecycle.py +0 -0
  556. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/middleware.py +0 -0
  557. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/py.typed +0 -0
  558. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/__init__.py +0 -0
  559. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/_body.py +0 -0
  560. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/adapter.py +0 -0
  561. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/config.py +0 -0
  562. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/jwt.py +0 -0
  563. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/autocrud.py +0 -0
  564. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/compiler.py +0 -0
  565. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/config.py +0 -0
  566. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/constants.py +0 -0
  567. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/cors.py +0 -0
  568. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/__init__.py +0 -0
  569. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
  570. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/app.py +0 -0
  571. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/health.py +0 -0
  572. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/openapi.py +0 -0
  573. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/response.py +0 -0
  574. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
  575. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/sql.py +0 -0
  576. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/middleware.py +0 -0
  577. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/model.py +0 -0
  578. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/rest_adapter.py +0 -0
  579. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/__init__.py +0 -0
  580. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/__init__.py +0 -0
  581. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
  582. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
  583. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
  584. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
  585. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
  586. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_errors.py +0 -0
  587. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_operators.py +0 -0
  588. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
  589. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
  590. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
  591. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
  592. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
  593. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
  594. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
  595. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
  596. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
  597. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
  598. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
  599. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
  600. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/runner.py +0 -0
  601. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/__init__.py +0 -0
  602. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/_bindings.py +0 -0
  603. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/_compiler.py +0 -0
  604. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/_errors.py +0 -0
  605. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/_plan.py +0 -0
  606. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
  607. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
  608. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/__init__.py +0 -0
  609. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_errors.py +0 -0
  610. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_exceptions.py +0 -0
  611. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_message.py +0 -0
  612. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_tracing.py +0 -0
  613. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_typing.py +0 -0
  614. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/graph/__init__.py +0 -0
  615. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/graph/_flow.py +0 -0
  616. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/__init__.py +0 -0
  617. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_codec.py +0 -0
  618. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_config.py +0 -0
  619. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_errors.py +0 -0
  620. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
  621. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_message.py +0 -0
  622. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_record.py +0 -0
  623. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_wire.py +0 -0
  624. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
  625. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
  626. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
  627. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
  628. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
  629. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
  630. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
  631. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
  632. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
  633. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/__init__.py +0 -0
  634. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
  635. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/_config.py +0 -0
  636. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/_event.py +0 -0
  637. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/_normalize.py +0 -0
  638. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/__init__.py +0 -0
  639. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_boundary.py +0 -0
  640. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_branches.py +0 -0
  641. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
  642. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
  643. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_decompose.py +0 -0
  644. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
  645. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
  646. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_fork.py +0 -0
  647. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_helpers.py +0 -0
  648. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_mongo.py +0 -0
  649. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_protocols.py +0 -0
  650. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_router.py +0 -0
  651. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_shape.py +0 -0
  652. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_sink.py +0 -0
  653. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_step.py +0 -0
  654. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
  655. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_table/common.py +0 -0
  656. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_table/config.py +0 -0
  657. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_with.py +0 -0
  658. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/refs.py +0 -0
  659. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/testing.py +0 -0
  660. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/__init__.py +0 -0
  661. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/agents.py +0 -0
  662. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/golden.py +0 -0
  663. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/http_harness.py +0 -0
  664. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/in_memory.py +0 -0
  665. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/repository_harness.py +0 -0
  666. {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/runner.py +0 -0
@@ -4,6 +4,61 @@
4
4
 
5
5
  ### core
6
6
 
7
+ - **core:** range-partitioned row-scoped tables.
8
+ `__partition_by__ = ("RANGE", "<column>")` on a `RowScoped` model compiles to
9
+ `postgresql_partition_by`; the column must be a `DateTime` column of the
10
+ primary key and every unique key must contain it, LIST and HASH are refused,
11
+ all at compile time. Partitions are created ahead of time by the migrator
12
+ through guard revision 2 (`0002.sql`, new functions `create_range_partition`
13
+ and `detach_partition`, `EXECUTE` for the owner only), which creates,
14
+ registers and protects each partition with its parent's scopes in the
15
+ caller's transaction: `op.ensure_range_partitions(table, start, end,
16
+ interval=...)` in a revision, or
17
+ `loom.core.repository.sqlalchemy.rls.ensure_range_partitions(url_or_connection,
18
+ application, model, start, end, interval=...)` at runtime. Partitions are
19
+ named `<table>_p<YYYYMM>` (`_p<YYYY>`, `_p<YYYYMMDD>` for year and day) with
20
+ midnight-UTC bounds. Retention uses `op.detach_range_partitions(...,
21
+ drop=...)` or `detach_range_partitions(...)`, which unprotects, detaches and
22
+ optionally drops. Dropping a partitioned table in an autogenerated revision
23
+ drops its partitions first (`op.drop_partitions`). `check` and `verify` count
24
+ registered partitions with their parent; `verify` reports
25
+ `partition.registration` for a partition registered unlike its parent.
26
+ Re-apply the bootstrap to install revision 2; partition calls on an older
27
+ guard raise `guard revision pending`. `ScopedTable` gains `partition_by`, and
28
+ `require_guard_revision(_sync)` take an optional `minimum`.
29
+ - **core:** a model declares named checks and partial unique indexes.
30
+ `__checks__ = {rule: sql_expression}` compiles one `CHECK` constraint per
31
+ rule, named by the rule; `__partial_unique__ = {rule: (columns, where)}`
32
+ compiles a unique index `uq_<table>_<rule>` restricted to the rows matching
33
+ `where`, and on a row-scoped table its columns must contain the boundary
34
+ (C5, refused at compile time as the guard refuses it with `LG002`). The
35
+ expression and the predicate are product code with the trust of a
36
+ hand-written Alembic revision and must be static literals with no runtime
37
+ input; loom checks only that each is a non-empty string. The static-SQL lint
38
+ exempts exactly the two calls that compile them and now also watches
39
+ `CheckConstraint`. Alembic's autogenerate does not compare checks or index
40
+ predicates, so adding, changing or removing a check on an existing table,
41
+ or changing a predicate, is a hand-written revision.
42
+ - **core:** `database.schema.naming_convention` hands a SQLAlchemy
43
+ `naming_convention` (`pk`, `fk`, `uq`, `ck`, `ix`) to the application
44
+ metadata of the migration path and to the metadata the REST runtime and the
45
+ Celery worker compile, so all of them name constraints alike; absent,
46
+ nothing changes. Use
47
+ `fk_%(table_name)s_%(column_0_N_name)s`: every composite FK of a scoped
48
+ table starts with the boundary column. Compilation now refuses two
49
+ constraints or indexes of one table resolving to the same name, and a
50
+ check, `__indexes__` or `__partial_unique__` name over Postgres's 63 bytes,
51
+ instead of failing or truncating at DDL time. `reset_registry` takes the
52
+ convention as `naming_convention=`; called without it, it leaves the
53
+ convention as it is, and `None` restores SQLAlchemy's default.
54
+
55
+ - **core:** two column types. `Bytes` (`loom.core.model.Bytes`, also inferred
56
+ from a `bytes` annotation, which used to fall back to `JSON`) compiles to
57
+ `LargeBinary`, `bytea` on Postgres; `Postgres.INET` compiles to Postgres
58
+ `inet`. The SQLAlchemy repository binds `bytes` as they are instead of
59
+ base64 text, and a network address the driver returns for `inet` reaches a
60
+ `str` field as its text form (`10.0.0.1`, `2001:db8::1/64`).
61
+
7
62
  - **core:** a memory cache alias can be bounded. `cache: max_size` (entries) and
8
63
  the new `cache: max_bytes` (stored payload bytes) serve every
9
64
  `aiocache.SimpleMemoryCache` alias through `loom.core.cache.memory.BoundedMemoryCache`,
@@ -85,12 +140,25 @@
85
140
 
86
141
  ### rest
87
142
 
143
+ - **rest:** a single `RuleViolation(field, message)` now answers its `field`.
144
+ `HttpErrorMapper` dropped it, so two `rule_violation` 422s could only be
145
+ told apart by their message text. The body adds `field` (`ErrorField.FIELD`,
146
+ the key each `violations` item of `RuleViolations` already carries) next to
147
+ the unchanged `code`, `message` and `trace_id`; the status stays `422`. This
148
+ includes the SQL endpoint's 422s, whose `field` is `sql` or `body`. Every
149
+ other error body is unchanged.
88
150
  - **rest:** a strict `pydantic.BaseModel` result, a `list` of them or an
89
151
  envelope holding one now renders directly on a REST route, through
90
152
  `MsgspecJSONResponse`'s `enc_hook`, and documents in OpenAPI
91
153
  (`_safe_pydantic_schema`) through the same `LoomType` the cache and MCP
92
154
  boundaries already use; `LoomRestAdapter`'s Struct projection goes
93
155
  through it too.
156
+ - **rest:** `create_app` accepts `modules: Sequence[Callable[[LoomContainer], None]]`,
157
+ mirroring the Celery `create_app`. Each module is called with the container,
158
+ in order, before repositories are registered and before use cases are
159
+ verified, so a use case can inject a port no repository provides (a clock,
160
+ an identity verifier, a bridge to another bounded context). Without the
161
+ module, startup still fails with the same `ResolutionError`.
94
162
 
95
163
  ### prefect
96
164
 
@@ -231,6 +299,15 @@
231
299
 
232
300
  ### core
233
301
 
302
+ - **core:** the RLS guard refuses, in the same statement, a drop outside the
303
+ hatch that breaks its invariants. `DROP POLICY` or `DROP TRIGGER
304
+ loom_deny_owner_dml` on a scoped table used to commit, because drops are not
305
+ reported to `ddl_command_end`; the schema then failed the assertion (`LG002`)
306
+ only at the next DDL. The `sql_drop` trigger now runs the assertion when the
307
+ drop removes an object of the application schema and the hatch is closed;
308
+ dropping a plain index still succeeds. Shipped in guard revision 2
309
+ (`0002.sql`, `CREATE OR REPLACE FUNCTION on_sql_drop`); re-apply the
310
+ bootstrap to install it.
234
311
  - **core:** a model with a relation or projection field imports again on
235
312
  Python 3.12.4 and later when its module uses
236
313
  `from __future__ import annotations`. It failed with
@@ -293,6 +370,19 @@
293
370
  capability does not recover yet; see "A session that died after it opened is
294
371
  replaced by the next call" in `docs/ai/mcp.md`.
295
372
 
373
+ ### rest
374
+
375
+ - **rest:** an authenticator can report an outage instead of answering `500`.
376
+ An exception raised inside `AuthenticationMiddleware` never reached
377
+ Starlette's exception handlers, so a custom authenticator whose identity
378
+ provider was unreachable answered a bare `500`. An authenticator now raises
379
+ `loom.rest.auth.AuthenticationUnavailable` and the request answers `503`
380
+ with the standard error body (`code: service_unavailable`, a fixed message,
381
+ `trace_id`) and no `WWW-Authenticate` challenge; the exception's message
382
+ and cause are logged at `WARNING`, never sent. `ErrorCode` gains
383
+ `SERVICE_UNAVAILABLE`, which `HttpErrorMapper` maps to `503`. Any other
384
+ exception from the authenticator, and the `401` refusal, are unchanged.
385
+
296
386
  ## ♻️ Refactor
297
387
 
298
388
  ### etl
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: loom-kernel
3
- Version: 2.12.0
3
+ Version: 2.14.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Classifier: Programming Language :: Python :: 3
@@ -118,6 +118,16 @@ _T = TypeVar("_T")
118
118
  # ---------------------------------------------------------------------------
119
119
 
120
120
 
121
+ class _WorkerSchemaConfig(msgspec.Struct, kw_only=True):
122
+ """The part of ``database.schema`` the worker compiles models with.
123
+
124
+ Attributes:
125
+ naming_convention: SQLAlchemy naming convention keyed by constraint kind.
126
+ """
127
+
128
+ naming_convention: dict[str, str] | None = None
129
+
130
+
121
131
  class _WorkerDbConfig(msgspec.Struct, kw_only=True):
122
132
  """Database settings for the worker process.
123
133
 
@@ -125,11 +135,13 @@ class _WorkerDbConfig(msgspec.Struct, kw_only=True):
125
135
  url: Async SQLAlchemy connection URL.
126
136
  echo: Log all SQL statements when ``True``.
127
137
  pool_pre_ping: Test connections before checkout.
138
+ schema: Schema settings the models are compiled with.
128
139
  """
129
140
 
130
141
  url: str
131
142
  echo: bool = False
132
143
  pool_pre_ping: bool = True
144
+ schema: _WorkerSchemaConfig = msgspec.field(default_factory=_WorkerSchemaConfig)
133
145
 
134
146
 
135
147
  class _DiscoveryModules(msgspec.Struct, kw_only=True):
@@ -621,16 +633,28 @@ def _register_repositories(
621
633
  return build_sqlalchemy_repository_registration_module(session_manager, models)
622
634
 
623
635
 
624
- def _compile_models(models: Sequence[type[BaseModel]]) -> tuple[type[BaseModel], ...]:
636
+ def _worker_naming_convention(ctx: ConfigContext) -> Mapping[str, str] | None:
637
+ """The ``database.schema.naming_convention`` the REST runtime and migrations also read."""
638
+ db_cfg = ctx.section(ConfigKey.DATABASE, _WorkerDbConfig)
639
+ return db_cfg.schema.naming_convention
640
+
641
+
642
+ def _compile_models(
643
+ models: Sequence[type[BaseModel]], *, naming_convention: Mapping[str, str] | None
644
+ ) -> tuple[type[BaseModel], ...]:
625
645
  """Compile and normalize discovered models for SQLAlchemy repositories."""
626
646
  if not models:
627
647
  return ()
628
648
  try:
629
- from loom.core.backend.sqlalchemy import compile_all, reset_registry
649
+ from loom.core.backend.sqlalchemy import (
650
+ compile_all,
651
+ configured_naming_convention,
652
+ reset_registry,
653
+ )
630
654
  except ImportError as exc:
631
655
  raise _sqlalchemy_extra_error() from exc
632
656
  ordered = tuple(dict.fromkeys(models))
633
- reset_registry()
657
+ reset_registry(naming_convention=configured_naming_convention(naming_convention))
634
658
  compile_all(*ordered)
635
659
  return ordered
636
660
 
@@ -656,6 +680,8 @@ def _compile_db_layer(
656
680
  session_manager: SessionManager | None,
657
681
  models: Sequence[type[BaseModel]],
658
682
  user_modules: Sequence[Callable[[LoomContainer], None]],
683
+ *,
684
+ naming_convention: Mapping[str, str] | None,
659
685
  ) -> tuple[tuple[type[BaseModel], ...], tuple[Callable[[LoomContainer], None], ...]]:
660
686
  """Compile models and register repositories; no-op when DB is not configured.
661
687
 
@@ -663,6 +689,7 @@ def _compile_db_layer(
663
689
  session_manager: Active session manager, or ``None`` for pure jobs.
664
690
  models: Model classes discovered or declared for this worker.
665
691
  user_modules: Container modules provided by the caller.
692
+ naming_convention: The configured ``database.schema.naming_convention``.
666
693
 
667
694
  Returns:
668
695
  Tuple of (normalized_models, runtime_modules). When no DB is
@@ -671,7 +698,7 @@ def _compile_db_layer(
671
698
  base = tuple(user_modules)
672
699
  if session_manager is None:
673
700
  return tuple(models), base
674
- normalized = _compile_models(models)
701
+ normalized = _compile_models(models, naming_convention=naming_convention)
675
702
  if not normalized:
676
703
  return tuple(models), base
677
704
  return normalized, (*base, _register_repositories(session_manager, normalized))
@@ -904,7 +931,10 @@ def bootstrap_worker(
904
931
  _apply_job_config_if_present(ctx, job_type)
905
932
 
906
933
  uow_factory, session_manager = _resolve_uow_factory(ctx)
907
- final_models, runtime_modules = _compile_db_layer(session_manager, resolved.models, modules)
934
+ convention = _worker_naming_convention(ctx) if session_manager is not None else None
935
+ final_models, runtime_modules = _compile_db_layer(
936
+ session_manager, resolved.models, modules, naming_convention=convention
937
+ )
908
938
  runtime_modules = (*runtime_modules, cache_module_for(ctx))
909
939
 
910
940
  resolved = _WorkerResolved(
@@ -11,13 +11,14 @@ from __future__ import annotations
11
11
 
12
12
  import json
13
13
  import re
14
- from collections.abc import Callable, Mapping
14
+ from collections.abc import Callable, Iterable, Iterator, Mapping
15
15
  from typing import Any, Final, get_args
16
16
 
17
17
  from sqlalchemy import Connection, Table, event, text
18
18
 
19
19
  from loom.core.config import ConfigError
20
20
  from loom.core.model.field import Reach
21
+ from loom.core.model.partition import PartitionRange
21
22
  from loom.core.model.privilege import Privilege
22
23
  from loom.core.model.scoped import ScopedTable
23
24
  from loom.core.schema_names import schema_identifier, sql_identifier
@@ -42,6 +43,21 @@ GRANT_TABLE: Final = (
42
43
  "CAST(:readers AS text[]), CAST(:writers AS text[]))"
43
44
  )
44
45
  ASSERT_SCHEMA: Final = "SELECT assert_scoped_schema()"
46
+ CREATE_RANGE_PARTITION: Final = (
47
+ "SELECT create_range_partition("
48
+ "to_regclass(quote_ident(:schema) || '.' || quote_ident(:table)), "
49
+ "CAST(:partition AS text), CAST(:lower AS text), CAST(:upper AS text))"
50
+ )
51
+ DETACH_PARTITION: Final = (
52
+ "SELECT detach_partition(to_regclass(quote_ident(:schema) || '.' || quote_ident(:table)), "
53
+ "CAST(:partition AS text), CAST(:drop AS boolean))"
54
+ )
55
+ PARTITIONS: Final = (
56
+ "SELECT c.relname FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid "
57
+ "WHERE i.inhparent = to_regclass(quote_ident(:schema) || '.' || quote_ident(:table)) "
58
+ "ORDER BY c.relname"
59
+ )
60
+ LANDING: Final = "SELECT current_user, current_schema()"
45
61
  GUARD_FIRST: Final = (
46
62
  "SELECT set_config('search_path', quote_ident(:guard) || ', pg_catalog, pg_temp', true)"
47
63
  )
@@ -62,6 +78,7 @@ MISSING_EVENT_TRIGGERS: Final = (
62
78
 
63
79
  Parameters = dict[str, Any]
64
80
  GuardCall = Callable[[Connection, Parameters], None]
81
+ PartitionCall = tuple[str, Parameters]
65
82
  _OPEN_HATCH: Final = text(OPEN_HATCH)
66
83
  _PROTECT: Final = text(PROTECT)
67
84
  _GRANT_TABLE: Final = text(GRANT_TABLE)
@@ -108,6 +125,45 @@ def grant_parameters(
108
125
  }
109
126
 
110
127
 
128
+ def create_partition_parameters(schema: str, table: str, partition: PartitionRange) -> Parameters:
129
+ """Bound parameters of :data:`CREATE_RANGE_PARTITION` for one partition of ``schema.table``."""
130
+ return {
131
+ **table_parameters(schema, table),
132
+ "partition": sql_identifier(partition.name),
133
+ "lower": partition.lower,
134
+ "upper": partition.upper,
135
+ }
136
+
137
+
138
+ def detach_partition_parameters(
139
+ schema: str, table: str, partition: str, *, drop: bool
140
+ ) -> Parameters:
141
+ """Bound parameters of :data:`DETACH_PARTITION` for one partition of ``schema.table``."""
142
+ return {**table_parameters(schema, table), "partition": sql_identifier(partition), "drop": drop}
143
+
144
+
145
+ def create_partition_calls(
146
+ schema: str, table: str, partitions: Iterable[PartitionRange]
147
+ ) -> Iterator[PartitionCall]:
148
+ """Each partition's name and the parameters of :data:`CREATE_RANGE_PARTITION`, in order.
149
+
150
+ The guard answers each call with whether it created the partition.
151
+ """
152
+ for partition in partitions:
153
+ yield partition.name, create_partition_parameters(schema, table, partition)
154
+
155
+
156
+ def detach_partition_calls(
157
+ schema: str, table: str, names: Iterable[str], *, drop: bool
158
+ ) -> Iterator[PartitionCall]:
159
+ """Each name and the parameters of :data:`DETACH_PARTITION`, in order.
160
+
161
+ The guard answers each call with whether the partition existed.
162
+ """
163
+ for name in names:
164
+ yield name, detach_partition_parameters(schema, table, name, drop=drop)
165
+
166
+
111
167
  def table_parameters(schema: str, table: str) -> Parameters:
112
168
  """The validated schema and table a guard call resolves inside Postgres."""
113
169
  return {"schema": schema_identifier(schema), "table": sql_identifier(table)}
@@ -1,21 +1,26 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import functools
4
+ from collections import deque
4
5
  from collections.abc import Mapping
5
6
  from dataclasses import dataclass, field
6
- from typing import Any
7
+ from enum import Enum
8
+ from typing import Any, Final
7
9
 
8
10
  import msgspec
9
11
  from sqlalchemy import (
10
12
  JSON,
11
13
  BigInteger,
12
14
  Boolean,
15
+ CheckConstraint,
16
+ Constraint,
13
17
  DateTime,
14
18
  Float,
15
19
  ForeignKey,
16
20
  ForeignKeyConstraint,
17
21
  Index,
18
22
  Integer,
23
+ LargeBinary,
19
24
  MetaData,
20
25
  Numeric,
21
26
  String,
@@ -23,21 +28,30 @@ from sqlalchemy import (
23
28
  Text,
24
29
  UniqueConstraint,
25
30
  func,
31
+ text,
26
32
  )
27
33
  from sqlalchemy.dialects.postgresql import ARRAY as PG_ARRAY
34
+ from sqlalchemy.dialects.postgresql import INET as PG_INET
28
35
  from sqlalchemy.dialects.postgresql import JSONB as PG_JSONB
29
36
  from sqlalchemy.dialects.postgresql import TSVECTOR as PG_TSVECTOR
30
37
  from sqlalchemy.dialects.postgresql import UUID as PG_UUID
31
38
  from sqlalchemy.orm import DeclarativeBase, mapped_column, relationship
32
39
  from sqlalchemy.orm import registry as sa_registry
40
+ from sqlalchemy.sql.naming import conv
41
+ from sqlalchemy.sql.schema import DEFAULT_NAMING_CONVENTION
33
42
 
34
43
  from loom.core.backend.core_model import CoreModel, CoreProfilePlan, CoreRelationStep
35
44
  from loom.core.backend.scoped_ddl import SCHEMA_KEY, register_listeners
45
+ from loom.core.config import ConfigError
36
46
  from loom.core.model.enums import Cardinality, OnDelete, ServerDefault, ServerOnUpdate
37
47
  from loom.core.model.field import ColumnType, Field
38
48
  from loom.core.model.introspection import (
39
49
  ColumnFieldInfo,
50
+ PartialUnique,
51
+ declared_checks,
40
52
  declared_indexes,
53
+ declared_partial_unique,
54
+ declared_partition,
41
55
  declared_privileges,
42
56
  declared_unique,
43
57
  extract_model_from_hint,
@@ -53,6 +67,7 @@ from loom.core.model.privilege import READ_WRITE, Privilege
53
67
  from loom.core.model.relation import Relation
54
68
  from loom.core.model.scoped import ScopeColumn, ScopedTable
55
69
  from loom.core.projection.runtime import ProjectionStep, build_projection_plan_from_steps
70
+ from loom.core.schema_names import MAX_IDENTIFIER_LENGTH, naming_convention
56
71
 
57
72
  _SA_TYPE_MAP: dict[str, type] = {
58
73
  "String": String,
@@ -62,11 +77,13 @@ _SA_TYPE_MAP: dict[str, type] = {
62
77
  "Boolean": Boolean,
63
78
  "Text": Text,
64
79
  "JSON": JSON,
80
+ "Bytes": LargeBinary,
65
81
  "DateTime": DateTime,
66
82
  "Numeric": Numeric,
67
83
  "Postgres.JSONB": PG_JSONB,
68
84
  "Postgres.UUID": PG_UUID,
69
85
  "Postgres.TSVECTOR": PG_TSVECTOR,
86
+ "Postgres.INET": PG_INET,
70
87
  }
71
88
 
72
89
  _SERVER_DEFAULT_MAP = {
@@ -105,6 +122,16 @@ class _Compilation:
105
122
 
106
123
 
107
124
  _COMPILATION_KEY = "loom.compilation"
125
+ _RULE_KEY = "loom.rule"
126
+
127
+
128
+ class _Keep(Enum):
129
+ """The default of :func:`reset_registry`: leave the naming convention as it is."""
130
+
131
+ CONVENTION = "keep"
132
+
133
+
134
+ _KEEP_CONVENTION: Final = _Keep.CONVENTION
108
135
 
109
136
 
110
137
  @functools.cache
@@ -211,6 +238,7 @@ def _compile_model(
211
238
  struct_cls, column_fields, boundary, models_by_table, comp
212
239
  )
213
240
  constraints += _declared_constraints(struct_cls, table_name)
241
+ partition = declared_partition(struct_cls)
214
242
 
215
243
  attrs: dict[str, Any] = {
216
244
  "__tablename__": table_name,
@@ -220,10 +248,15 @@ def _compile_model(
220
248
  attrs[name] = _build_mapped_column(
221
249
  field_info, inline_foreign_key=name not in composite_columns
222
250
  )
223
- if constraints:
224
- attrs["__table_args__"] = tuple(constraints)
251
+ table_args: list[Any] = list(constraints)
252
+ if partition is not None:
253
+ table_args.append({"postgresql_partition_by": f"RANGE ({partition.column})"})
254
+ if table_args:
255
+ attrs["__table_args__"] = tuple(table_args)
225
256
 
226
257
  sa_cls: Any = type(struct_cls.__name__ + "SA", (comp.base,), attrs)
258
+ _check_declared_name_lengths(struct_cls, constraints)
259
+ _check_distinct_names(struct_cls, sa_cls.__table__)
227
260
  comp.compiled[struct_cls] = sa_cls
228
261
  comp.tables[table_name] = sa_cls
229
262
  comp.pending[struct_cls] = get_relations(struct_cls)
@@ -235,6 +268,7 @@ def _compile_model(
235
268
  name=table.name,
236
269
  scopes=scopes,
237
270
  privileges=frozenset(getattr(struct_cls, "__scope_privileges__", READ_WRITE)),
271
+ partition_by=None if partition is None else partition.column,
238
272
  )
239
273
  comp.scoped[(table.schema, table.name)] = scoped
240
274
  schema = comp.metadata.info.get(SCHEMA_KEY)
@@ -248,15 +282,109 @@ def _compile_model(
248
282
  return sa_cls
249
283
 
250
284
 
251
- def _declared_constraints(struct_cls: type, table_name: str) -> list[Any]:
252
- constraints: list[Any] = [UniqueConstraint(*columns) for columns in declared_unique(struct_cls)]
285
+ def _declared_constraints(struct_cls: type, table_name: str) -> list[Constraint | Index]:
286
+ """Keys, indexes and checks declared on the model, in declaration order.
287
+
288
+ ``__unique__`` constraints are unnamed, so the metadata's naming convention
289
+ names them. ``__checks__`` are named by their rule, which a ``ck``
290
+ convention may use as ``%(constraint_name)s``. Indexes carry a name loom
291
+ builds; :class:`~sqlalchemy.sql.naming.conv` marks it final so no convention
292
+ renames it, and :func:`_check_declared_name_lengths` refuses one over
293
+ Postgres's limit.
294
+
295
+ Alembic's autogenerate does not compare CHECK constraints and does not
296
+ compare the ``WHERE`` predicate of an index: adding, changing or removing a
297
+ check on an existing table, and changing a predicate, are written by hand in
298
+ a revision, and ``check`` does not report them as drift.
299
+ """
300
+ constraints: list[Constraint | Index] = [
301
+ UniqueConstraint(*columns) for columns in declared_unique(struct_cls)
302
+ ]
253
303
  constraints += [
254
- Index(f"ix_{table_name}_{'_'.join(columns)}", *columns)
304
+ Index(
305
+ conv(f"ix_{table_name}_{'_'.join(columns)}"),
306
+ *columns,
307
+ info={_RULE_KEY: ("__indexes__", ", ".join(columns))},
308
+ )
255
309
  for columns in declared_indexes(struct_cls)
256
310
  ]
311
+ constraints += [
312
+ _partial_unique_index(table_name, partial)
313
+ for partial in declared_partial_unique(struct_cls)
314
+ ]
315
+ constraints += [
316
+ _check_constraint(rule, expression)
317
+ for rule, expression in declared_checks(struct_cls).items()
318
+ ]
257
319
  return constraints
258
320
 
259
321
 
322
+ def _check_distinct_names(struct_cls: type, table: Table) -> None:
323
+ """Refuse a table where two constraints or indexes resolve to the same name.
324
+
325
+ Postgres would reject the second one at DDL time. Under a naming
326
+ convention the usual cause is ``fk_%(table_name)s_%(column_0_name)s``: every
327
+ composite FK of a scoped table starts with the boundary column.
328
+ """
329
+ seen: set[str] = set()
330
+ items: list[Constraint | Index] = [*table.constraints, *table.indexes]
331
+ for item in items:
332
+ if item.name is None:
333
+ continue
334
+ name = str(item.name)
335
+ if name in seen:
336
+ raise ValueError(
337
+ f"{struct_cls.__name__}: table {table.name} has two constraints named {name!r}; "
338
+ "name them apart, for FKs with fk_%(table_name)s_%(column_0_N_name)s"
339
+ )
340
+ seen.add(name)
341
+
342
+
343
+ def _partial_unique_index(table_name: str, partial: PartialUnique) -> Index:
344
+ """The unique index of one ``__partial_unique__`` rule.
345
+
346
+ ``partial.where`` is a DDL fragment the product declared on its model. It
347
+ must be a static literal with no runtime input; loom checks only that it is
348
+ a non-empty string.
349
+ """
350
+ return Index(
351
+ conv(f"uq_{table_name}_{partial.rule}"),
352
+ *partial.columns,
353
+ unique=True,
354
+ postgresql_where=text(partial.where),
355
+ info={_RULE_KEY: ("__partial_unique__", partial.rule)},
356
+ )
357
+
358
+
359
+ def _check_constraint(rule: str, expression: str) -> CheckConstraint:
360
+ """The CHECK constraint of one ``__checks__`` rule.
361
+
362
+ ``expression`` is a DDL fragment the product declared on its model. It must
363
+ be a static literal with no runtime input; loom checks only that it is a
364
+ non-empty string.
365
+ """
366
+ return CheckConstraint(expression, name=rule, info={_RULE_KEY: ("__checks__", rule)})
367
+
368
+
369
+ def _check_declared_name_lengths(struct_cls: type, constraints: list[Constraint | Index]) -> None:
370
+ """Refuse a declared check or index whose final name Postgres would truncate.
371
+
372
+ SQLAlchemy would raise only when emitting DDL for a plain name, and would
373
+ shorten a final (``conv``) name with a hash; both are refused here instead.
374
+ """
375
+ for constraint in constraints:
376
+ declared = constraint.info.get(_RULE_KEY)
377
+ if declared is None:
378
+ continue
379
+ attr, rule = declared
380
+ name = str(constraint.name)
381
+ if len(name.encode()) > MAX_IDENTIFIER_LENGTH:
382
+ raise ValueError(
383
+ f"{struct_cls.__name__}: {attr} rule {rule!r} is named {name!r}, longer than "
384
+ f"the {MAX_IDENTIFIER_LENGTH} bytes Postgres keeps; shorten it"
385
+ )
386
+
387
+
260
388
  def _target_model(
261
389
  table: str, models_by_table: Mapping[str, type], comp: _Compilation
262
390
  ) -> type | None:
@@ -549,29 +677,48 @@ def _topological_sort(
549
677
  ) -> list[type]:
550
678
  """Kahn's algorithm: return *models* with dependency leaves first.
551
679
 
552
- If a cycle is detected (remaining nodes after BFS exhaustion), the
553
- cyclic models are appended in arbitrary order. Circular references
554
- are valid because ``compile_model`` is idempotent and relationships
555
- are resolved after all models are registered.
680
+ Ties are released in the input order of *models*. If a cycle is detected
681
+ (remaining nodes after BFS exhaustion), the cyclic models are appended in
682
+ their input order. Circular references are valid because
683
+ ``compile_model`` is idempotent and relationships are resolved after all
684
+ models are registered.
556
685
  """
557
- from collections import deque
686
+ in_degree, dependents = _dependency_graph(models, deps)
687
+ result = _release_in_dependency_order(models, in_degree, dependents)
688
+ processed = set(result)
689
+ result.extend(m for m in models if m not in processed)
690
+ return result
558
691
 
559
- model_set = set(models)
560
692
 
561
- # in_degree[m] = number of m's deps that are within our compilation set
693
+ def _dependency_graph(
694
+ models: list[type],
695
+ deps: dict[type, frozenset[type]],
696
+ ) -> tuple[dict[type, int], dict[type, list[type]]]:
697
+ """Index the dependency edges that stay within *models*.
698
+
699
+ Returns:
700
+ ``in_degree[m]``: how many of ``m``'s deps are in *models*, and
701
+ ``dependents[dep]``: the models depending on ``dep``, in input order.
702
+ """
703
+ model_set = set(models)
562
704
  in_degree: dict[type, int] = dict.fromkeys(models, 0)
563
- # dependents[dep] = list of models that depend on dep
564
705
  dependents: dict[type, list[type]] = {m: [] for m in models}
565
-
566
706
  for m in models:
567
707
  for dep in deps.get(m, frozenset()):
568
708
  if dep in model_set:
569
709
  in_degree[m] += 1
570
710
  dependents[dep].append(m)
711
+ return in_degree, dependents
712
+
571
713
 
714
+ def _release_in_dependency_order(
715
+ models: list[type],
716
+ in_degree: dict[type, int],
717
+ dependents: dict[type, list[type]],
718
+ ) -> list[type]:
719
+ """Run Kahn's BFS, consuming *in_degree*; models left in a cycle are omitted."""
572
720
  queue: deque[type] = deque(m for m in models if in_degree[m] == 0)
573
721
  result: list[type] = []
574
-
575
722
  while queue:
576
723
  node = queue.popleft()
577
724
  result.append(node)
@@ -579,10 +726,6 @@ def _topological_sort(
579
726
  in_degree[dependent] -= 1
580
727
  if in_degree[dependent] == 0:
581
728
  queue.append(dependent)
582
-
583
- # Cyclic nodes: append in original order
584
- processed = set(result)
585
- result.extend(m for m in models if m not in processed)
586
729
  return result
587
730
 
588
731
 
@@ -600,8 +743,6 @@ def _resolve_compile_closure(*roots: type) -> tuple[type, ...]:
600
743
  Returns:
601
744
  Tuple of all models (roots + transitive deps) in compilation order.
602
745
  """
603
- from collections import deque
604
-
605
746
  seen: set[type] = set()
606
747
  all_deps: dict[type, frozenset[type]] = {}
607
748
  queue: deque[type] = deque(roots)
@@ -678,8 +819,29 @@ def get_metadata() -> MetaData:
678
819
  return SABase.metadata
679
820
 
680
821
 
681
- def reset_registry() -> None:
682
- """Clear compiled models — primarily for testing."""
822
+ def configured_naming_convention(value: Mapping[str, str] | None) -> dict[str, str] | None:
823
+ """Validate the ``database.schema.naming_convention`` setting.
824
+
825
+ Raises:
826
+ ConfigError: Naming the setting and the first unknown kind.
827
+ """
828
+ try:
829
+ return naming_convention(value)
830
+ except ValueError as exc:
831
+ raise ConfigError(f"database.schema.naming_convention: {exc}") from exc
832
+
833
+
834
+ def reset_registry(
835
+ *, naming_convention: Mapping[str, str] | None | _Keep = _KEEP_CONVENTION
836
+ ) -> None:
837
+ """Clear compiled models and, when asked, set the shared metadata's naming convention.
838
+
839
+ The runtime compiles into the shared metadata after this call, so the
840
+ convention it receives, the one ``database.schema.naming_convention``
841
+ declares, names the tables ``create_all`` creates exactly as the
842
+ application metadata of the migration path does. Without the argument the
843
+ convention is left as it is; ``None`` restores SQLAlchemy's default.
844
+ """
683
845
  _registry.clear()
684
846
  _table_registry.clear()
685
847
  _core_registry.clear()
@@ -687,6 +849,11 @@ def reset_registry() -> None:
687
849
  _shared().scoped.clear()
688
850
  SABase.metadata.clear()
689
851
  SABase.registry.dispose()
852
+ if naming_convention is _KEEP_CONVENTION:
853
+ return
854
+ SABase.metadata.naming_convention = (
855
+ dict(naming_convention) if naming_convention else DEFAULT_NAMING_CONVENTION
856
+ )
690
857
 
691
858
 
692
859
  # ---------------------------------------------------------------------------