loom-kernel 2.22.3__tar.gz → 4.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (696) hide show
  1. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/CHANGELOG.md +201 -0
  2. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/PKG-INFO +5 -1
  3. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/README.md +4 -0
  4. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/auto.py +11 -1
  5. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/bootstrap.py +47 -16
  6. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/config.py +7 -5
  7. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/cli/app.py +3 -1
  8. loom_kernel-4.0.0/src/loom/cli/check.py +105 -0
  9. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/bootstrap/bootstrap.py +9 -0
  10. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/bootstrap/kernel.py +8 -0
  11. loom_kernel-4.0.0/src/loom/core/checks.py +343 -0
  12. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/context.py +25 -1
  13. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/keys.py +0 -2
  14. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/observability.py +1 -1
  15. loom_kernel-4.0.0/src/loom/core/config/overrides.py +317 -0
  16. loom_kernel-4.0.0/src/loom/core/environment.py +293 -0
  17. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/locator.py +40 -12
  18. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/__init__.py +2 -2
  19. loom_kernel-4.0.0/src/loom/core/logger/checks.py +46 -0
  20. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/config.py +70 -76
  21. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/introspection.py +26 -0
  22. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/types.py +5 -0
  23. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/config.py +10 -4
  24. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/runtime.py +17 -6
  25. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/backend.py +1 -1
  26. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/mixins.py +4 -11
  27. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +17 -3
  28. loom_kernel-4.0.0/src/loom/core/repository/sqlalchemy/values.py +51 -0
  29. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/config.py +17 -13
  30. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_streaming.py +2 -2
  31. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/_config.py +1 -1
  32. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/config_loader.py +24 -8
  33. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/core.py +89 -9
  34. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/_config.py +15 -15
  35. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/spark.py +3 -3
  36. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/__init__.py +1 -1
  37. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_config.py +1 -1
  38. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_ctx.py +0 -2
  39. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_flow_yaml.py +12 -4
  40. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_meta.py +3 -6
  41. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/_discovery.py +45 -39
  42. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/_yaml_etls.py +4 -3
  43. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/entrypoint.py +4 -5
  44. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_assemble.py +2 -1
  45. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_backfill.py +3 -3
  46. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_backfill_body.py +17 -7
  47. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_body.py +13 -5
  48. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_hooks.py +14 -4
  49. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_maintenance.py +12 -9
  50. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_signature.py +12 -4
  51. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_event.py +2 -3
  52. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/__init__.py +5 -0
  53. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/config.py +3 -3
  54. loom_kernel-4.0.0/src/loom/rest/checks.py +64 -0
  55. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/compiler.py +141 -6
  56. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/config.py +21 -2
  57. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/cors.py +1 -1
  58. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/auto.py +130 -67
  59. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/router_runtime.py +117 -32
  60. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/model.py +44 -1
  61. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/runner.py +72 -35
  62. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_config.py +14 -8
  63. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/_config.py +2 -2
  64. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/.gitignore +0 -0
  65. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/LICENSE +0 -0
  66. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/pyproject.toml +0 -0
  67. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/__init__.py +0 -0
  68. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/__init__.py +0 -0
  69. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_concurrency.py +0 -0
  70. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_filters.py +0 -0
  71. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_paths.py +0 -0
  72. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_roles.py +0 -0
  73. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_startup.py +0 -0
  74. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_transport.py +0 -0
  75. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_usecase.py +0 -0
  76. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/__init__.py +0 -0
  77. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/_binding.py +0 -0
  78. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/_handlers.py +0 -0
  79. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/_rpc.py +0 -0
  80. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/card.py +0 -0
  81. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/events.py +0 -0
  82. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/server.py +0 -0
  83. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/abc.py +0 -0
  84. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/bootstrap.py +0 -0
  85. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/__init__.py +0 -0
  86. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/_compiler.py +0 -0
  87. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/_fingerprint.py +0 -0
  88. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/_plan.py +0 -0
  89. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
  90. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
  91. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
  92. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
  93. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
  94. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
  95. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
  96. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
  97. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_output.py +0 -0
  98. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_state.py +0 -0
  99. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/config.py +0 -0
  100. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/__init__.py +0 -0
  101. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/_envelope.py +0 -0
  102. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/_schema.py +0 -0
  103. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/_v1.py +0 -0
  104. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
  105. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/describe.py +0 -0
  106. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/__init__.py +0 -0
  107. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
  108. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
  109. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
  110. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
  111. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
  112. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
  113. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
  114. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
  115. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
  116. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
  117. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
  118. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
  119. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
  120. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
  121. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
  122. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
  123. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
  124. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
  125. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
  126. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
  127. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
  128. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
  129. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
  130. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
  131. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
  132. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
  133. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
  134. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
  135. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
  136. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
  137. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
  138. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/errors.py +0 -0
  139. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/__init__.py +0 -0
  140. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_batch.py +0 -0
  141. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_columns.py +0 -0
  142. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_frames.py +0 -0
  143. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_ledger.py +0 -0
  144. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_runner.py +0 -0
  145. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_validation.py +0 -0
  146. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/fastapi/__init__.py +0 -0
  147. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/fastapi/endpoints.py +0 -0
  148. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/fastapi/response.py +0 -0
  149. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/fastapi/streaming.py +0 -0
  150. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/inference.py +0 -0
  151. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/pricing.py +0 -0
  152. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/registry.py +0 -0
  153. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/remote_auth.py +0 -0
  154. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/__init__.py +0 -0
  155. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_bounded.py +0 -0
  156. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_chain.py +0 -0
  157. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_conversation.py +0 -0
  158. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_grants.py +0 -0
  159. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_handle.py +0 -0
  160. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_health.py +0 -0
  161. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_hooks.py +0 -0
  162. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
  163. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_limits.py +0 -0
  164. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_mcp.py +0 -0
  165. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/validate/__init__.py +0 -0
  166. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/validate/__main__.py +0 -0
  167. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/__init__.py +0 -0
  168. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/constants.py +0 -0
  169. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/runner.py +0 -0
  170. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/service.py +0 -0
  171. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/cli/__init__.py +0 -0
  172. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/cli/schema.py +0 -0
  173. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/async_bridge.py +0 -0
  174. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/__init__.py +0 -0
  175. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/_decide.py +0 -0
  176. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/_grants.py +0 -0
  177. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/_roles.py +0 -0
  178. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/_scope.py +0 -0
  179. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/elevation.py +0 -0
  180. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/product.py +0 -0
  181. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/__init__.py +0 -0
  182. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/core_model.py +0 -0
  183. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/protocol.py +0 -0
  184. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/scoped_ddl.py +0 -0
  185. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/sqlalchemy.py +0 -0
  186. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/bootstrap/__init__.py +0 -0
  187. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/__init__.py +0 -0
  188. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/_batching.py +0 -0
  189. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/_single_flight.py +0 -0
  190. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/abc/__init__.py +0 -0
  191. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/abc/backend.py +0 -0
  192. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/abc/config.py +0 -0
  193. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/abc/dependency.py +0 -0
  194. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/calls.py +0 -0
  195. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/codec.py +0 -0
  196. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/decorators.py +0 -0
  197. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/dependency.py +0 -0
  198. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/errors.py +0 -0
  199. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/gateway.py +0 -0
  200. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/keys.py +0 -0
  201. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/memory.py +0 -0
  202. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/repository.py +0 -0
  203. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/result_codec.py +0 -0
  204. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/serializer.py +0 -0
  205. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/wiring.py +0 -0
  206. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/__init__.py +0 -0
  207. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/adapter.py +0 -0
  208. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/base.py +0 -0
  209. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/field.py +0 -0
  210. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/introspection.py +0 -0
  211. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/compiler.py +0 -0
  212. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/__init__.py +0 -0
  213. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/_boto3.py +0 -0
  214. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/_includes.py +0 -0
  215. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/_resolver_utils.py +0 -0
  216. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/binder.py +0 -0
  217. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/configurable.py +0 -0
  218. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/errors.py +0 -0
  219. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/loader.py +0 -0
  220. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/model.py +0 -0
  221. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/resolver.py +0 -0
  222. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/secrets.py +0 -0
  223. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/ssm.py +0 -0
  224. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/contracts/__init__.py +0 -0
  225. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/contracts/manifest.py +0 -0
  226. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/di/__init__.py +0 -0
  227. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/di/container.py +0 -0
  228. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/di/scope.py +0 -0
  229. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/__init__.py +0 -0
  230. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/_utils.py +0 -0
  231. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/base.py +0 -0
  232. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/interfaces.py +0 -0
  233. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/manifest.py +0 -0
  234. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/modules.py +0 -0
  235. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/__init__.py +0 -0
  236. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/compilable.py +0 -0
  237. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/compiler.py +0 -0
  238. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/events.py +0 -0
  239. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/executor.py +0 -0
  240. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/metrics.py +0 -0
  241. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/plan.py +0 -0
  242. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/post_commit.py +0 -0
  243. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/errors/__init__.py +0 -0
  244. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/errors/codes.py +0 -0
  245. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/errors/errors.py +0 -0
  246. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/expr/__init__.py +0 -0
  247. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/expr/eval.py +0 -0
  248. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/expr/nodes.py +0 -0
  249. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/expr/refs.py +0 -0
  250. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/__init__.py +0 -0
  251. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/context.py +0 -0
  252. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/identity.py +0 -0
  253. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/issuer.py +0 -0
  254. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/wire.py +0 -0
  255. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/introspection/__init__.py +0 -0
  256. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/introspection/base.py +0 -0
  257. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/introspection/describe.py +0 -0
  258. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/__init__.py +0 -0
  259. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/callback.py +0 -0
  260. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/context.py +0 -0
  261. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/handle.py +0 -0
  262. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/job.py +0 -0
  263. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/service.py +0 -0
  264. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/abc.py +0 -0
  265. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/registry.py +0 -0
  266. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/structlogger.py +0 -0
  267. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/__init__.py +0 -0
  268. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/_json_schema.py +0 -0
  269. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/_loom_type.py +0 -0
  270. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/base.py +0 -0
  271. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/convert.py +0 -0
  272. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/enums.py +0 -0
  273. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/field.py +0 -0
  274. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/partition.py +0 -0
  275. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/privilege.py +0 -0
  276. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/projection.py +0 -0
  277. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/relation.py +0 -0
  278. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/scoped.py +0 -0
  279. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/struct.py +0 -0
  280. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/timestamped.py +0 -0
  281. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/types_postgres.py +0 -0
  282. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/__init__.py +0 -0
  283. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/event.py +0 -0
  284. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/observer/__init__.py +0 -0
  285. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/observer/noop.py +0 -0
  286. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/observer/otel.py +0 -0
  287. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/observer/structlog.py +0 -0
  288. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/otel_ids.py +0 -0
  289. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/protocol.py +0 -0
  290. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/span.py +0 -0
  291. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/topology.py +0 -0
  292. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/persistence/__init__.py +0 -0
  293. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/persistence/abc.py +0 -0
  294. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/persistence/none.py +0 -0
  295. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/persistence/registry.py +0 -0
  296. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/plugins/__init__.py +0 -0
  297. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/plugins/entrypoints.py +0 -0
  298. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/plugins/optional.py +0 -0
  299. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/projection/__init__.py +0 -0
  300. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/projection/loaders.py +0 -0
  301. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/projection/runtime.py +0 -0
  302. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/__init__.py +0 -0
  303. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/__init__.py +0 -0
  304. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/cursor.py +0 -0
  305. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/errors.py +0 -0
  306. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/query.py +0 -0
  307. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
  308. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  309. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/repository.py +0 -0
  310. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/session_scope.py +0 -0
  311. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
  312. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
  313. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
  314. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
  315. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/__init__.py +0 -0
  316. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/backend.py +0 -0
  317. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/ids.py +0 -0
  318. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
  319. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/registry.py +0 -0
  320. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/repository.py +0 -0
  321. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/uow.py +0 -0
  322. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/values.py +0 -0
  323. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mutation.py +0 -0
  324. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/registration.py +0 -0
  325. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/registry.py +0 -0
  326. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  327. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/backend.py +0 -0
  328. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  329. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  330. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
  331. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
  332. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
  333. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
  334. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +0 -0
  335. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  336. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  337. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  338. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  339. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  340. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  341. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  342. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  343. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  344. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  345. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  346. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  347. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +0 -0
  348. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
  349. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
  350. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
  351. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
  352. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
  353. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
  354. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -0
  355. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +0 -0
  356. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
  357. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
  358. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
  359. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
  360. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +0 -0
  361. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
  362. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
  363. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  364. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  365. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/response/__init__.py +0 -0
  366. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/response/base.py +0 -0
  367. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/routing/__init__.py +0 -0
  368. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/routing/ref.py +0 -0
  369. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/routing/resolver.py +0 -0
  370. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/runner.py +0 -0
  371. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/schema/__init__.py +0 -0
  372. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/schema/schema_mode.py +0 -0
  373. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/schema_names.py +0 -0
  374. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/__init__.py +0 -0
  375. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/abc/__init__.py +0 -0
  376. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/abc/contracts.py +0 -0
  377. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/abc/errors.py +0 -0
  378. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/caller_bound.py +0 -0
  379. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
  380. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
  381. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
  382. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
  383. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/roles.py +0 -0
  384. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/service.py +0 -0
  385. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/symbols.py +0 -0
  386. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/tracing/__init__.py +0 -0
  387. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/tracing/context.py +0 -0
  388. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/transaction.py +0 -0
  389. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/transport/__init__.py +0 -0
  390. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/transport/adapter.py +0 -0
  391. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/uow/__init__.py +0 -0
  392. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/uow/abc.py +0 -0
  393. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/uow/context.py +0 -0
  394. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/__init__.py +0 -0
  395. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/_predicates.py +0 -0
  396. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/agent_markers.py +0 -0
  397. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/compute.py +0 -0
  398. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/constants.py +0 -0
  399. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/factory.py +0 -0
  400. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/field_ref.py +0 -0
  401. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/invoker.py +0 -0
  402. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/keys.py +0 -0
  403. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/markers.py +0 -0
  404. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/mcp_markers.py +0 -0
  405. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/outcome.py +0 -0
  406. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/registry.py +0 -0
  407. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/rule.py +0 -0
  408. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/use_case.py +0 -0
  409. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/__init__.py +0 -0
  410. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/_uri.py +0 -0
  411. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/__init__.py +0 -0
  412. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_format_registry.py +0 -0
  413. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
  414. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_common.py +0 -0
  415. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_log.py +0 -0
  416. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
  417. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
  418. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
  419. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_merge.py +0 -0
  420. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_path_template.py +0 -0
  421. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_predicate.py +0 -0
  422. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  423. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  424. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  425. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_write_policy.py +0 -0
  426. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/__init__.py +0 -0
  427. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  428. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  429. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_frame.py +0 -0
  430. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_historify.py +0 -0
  431. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  432. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_reader.py +0 -0
  433. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  434. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  435. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_writer.py +0 -0
  436. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/provider.py +0 -0
  437. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  438. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  439. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_historify.py +0 -0
  440. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  441. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  442. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  443. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_writer.py +0 -0
  444. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/provider.py +0 -0
  445. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/__init__.py +0 -0
  446. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
  447. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  448. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
  449. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_options.py +0 -0
  450. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  451. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  452. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_store.py +0 -0
  453. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/__init__.py +0 -0
  454. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_binding.py +0 -0
  455. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_compiler.py +0 -0
  456. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_errors.py +0 -0
  457. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_filter.py +0 -0
  458. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_plan.py +0 -0
  459. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators.py +0 -0
  460. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators_agents.py +0 -0
  461. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators_config.py +0 -0
  462. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  463. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators_step.py +0 -0
  464. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/__init__.py +0 -0
  465. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_format.py +0 -0
  466. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_read_options.py +0 -0
  467. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_utils.py +0 -0
  468. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_with_agent.py +0 -0
  469. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_write_options.py +0 -0
  470. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  471. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  472. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  473. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  474. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
  475. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/__init__.py +0 -0
  476. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from.py +0 -0
  477. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
  478. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
  479. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
  480. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
  481. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_specs.py +0 -0
  482. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/__init__.py +0 -0
  483. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_client.py +0 -0
  484. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_errors.py +0 -0
  485. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_file.py +0 -0
  486. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
  487. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
  488. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
  489. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
  490. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
  491. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
  492. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_into.py +0 -0
  493. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
  494. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_table.py +0 -0
  495. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  496. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/executor/__init__.py +0 -0
  497. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/executor/_agents.py +0 -0
  498. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  499. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/executor/_executor.py +0 -0
  500. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/__init__.py +0 -0
  501. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/_registry.py +0 -0
  502. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/__init__.py +0 -0
  503. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
  504. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
  505. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
  506. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
  507. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_mongo.py +0 -0
  508. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
  509. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
  510. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
  511. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_serialization.py +0 -0
  512. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/targets/__init__.py +0 -0
  513. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
  514. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/__init__.py +0 -0
  515. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/_observer.py +0 -0
  516. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/_records.py +0 -0
  517. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
  518. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
  519. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
  520. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
  521. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/__init__.py +0 -0
  522. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_builder.py +0 -0
  523. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_ops.py +0 -0
  524. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_protocol.py +0 -0
  525. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_runner.py +0 -0
  526. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_step.py +0 -0
  527. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
  528. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
  529. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/__init__.py +0 -0
  530. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_generics.py +0 -0
  531. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_params.py +0 -0
  532. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  533. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_process.py +0 -0
  534. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_sql.py +0 -0
  535. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_step.py +0 -0
  536. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_step_client.py +0 -0
  537. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  538. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/__init__.py +0 -0
  539. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/_agents.py +0 -0
  540. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/_providers.py +0 -0
  541. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/_wiring.py +0 -0
  542. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/errors.py +0 -0
  543. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/filtering.py +0 -0
  544. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runtime/__init__.py +0 -0
  545. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runtime/_config_values.py +0 -0
  546. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runtime/contracts.py +0 -0
  547. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/schema/__init__.py +0 -0
  548. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/schema/_contract.py +0 -0
  549. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/schema/_schema.py +0 -0
  550. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/__init__.py +0 -0
  551. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/_file_locator.py +0 -0
  552. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/_locator.py +0 -0
  553. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/routing.py +0 -0
  554. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/__init__.py +0 -0
  555. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/_result.py +0 -0
  556. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/_runners.py +0 -0
  557. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/_scenario.py +0 -0
  558. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/_stubs.py +0 -0
  559. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_async.py +0 -0
  560. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_placeholders.py +0 -0
  561. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_summary.py +0 -0
  562. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/__init__.py +0 -0
  563. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/_schedule.py +0 -0
  564. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/__init__.py +0 -0
  565. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_common.py +0 -0
  566. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_factory.py +0 -0
  567. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_params.py +0 -0
  568. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_run_name.py +0 -0
  569. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_runtime.py +0 -0
  570. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_stages.py +0 -0
  571. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/manifest/__init__.py +0 -0
  572. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/manifest/_model.py +0 -0
  573. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/manifest/_s3.py +0 -0
  574. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/manifest/_store.py +0 -0
  575. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/__init__.py +0 -0
  576. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_factory.py +0 -0
  577. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_format.py +0 -0
  578. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_port.py +0 -0
  579. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_slack.py +0 -0
  580. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_sns.py +0 -0
  581. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/__init__.py +0 -0
  582. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/_flow.py +0 -0
  583. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
  584. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/_manifest.py +0 -0
  585. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/_task_run.py +0 -0
  586. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/__init__.py +0 -0
  587. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/_instruments.py +0 -0
  588. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/adapter.py +0 -0
  589. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/kafka.py +0 -0
  590. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/lifecycle.py +0 -0
  591. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/middleware.py +0 -0
  592. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/py.typed +0 -0
  593. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/_body.py +0 -0
  594. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/adapter.py +0 -0
  595. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/__init__.py +0 -0
  596. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/abc.py +0 -0
  597. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/jwt.py +0 -0
  598. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/middleware.py +0 -0
  599. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/autocrud.py +0 -0
  600. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/constants.py +0 -0
  601. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/errors.py +0 -0
  602. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/__init__.py +0 -0
  603. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/_errors.py +0 -0
  604. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
  605. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/app.py +0 -0
  606. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/health.py +0 -0
  607. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/openapi.py +0 -0
  608. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/response.py +0 -0
  609. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/sql.py +0 -0
  610. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/middleware.py +0 -0
  611. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/rest_adapter.py +0 -0
  612. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/__init__.py +0 -0
  613. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/__init__.py +0 -0
  614. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
  615. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
  616. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
  617. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
  618. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
  619. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_errors.py +0 -0
  620. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_operators.py +0 -0
  621. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
  622. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
  623. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
  624. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
  625. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
  626. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
  627. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
  628. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
  629. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
  630. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
  631. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
  632. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
  633. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/__init__.py +0 -0
  634. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/_bindings.py +0 -0
  635. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/_compiler.py +0 -0
  636. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/_errors.py +0 -0
  637. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/_plan.py +0 -0
  638. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
  639. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
  640. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/__init__.py +0 -0
  641. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_errors.py +0 -0
  642. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_exceptions.py +0 -0
  643. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_message.py +0 -0
  644. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_tracing.py +0 -0
  645. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_typing.py +0 -0
  646. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/graph/__init__.py +0 -0
  647. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/graph/_flow.py +0 -0
  648. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/__init__.py +0 -0
  649. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_codec.py +0 -0
  650. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_errors.py +0 -0
  651. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
  652. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_message.py +0 -0
  653. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_record.py +0 -0
  654. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_wire.py +0 -0
  655. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
  656. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
  657. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
  658. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
  659. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
  660. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
  661. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
  662. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
  663. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
  664. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/__init__.py +0 -0
  665. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
  666. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/_event.py +0 -0
  667. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/_normalize.py +0 -0
  668. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/__init__.py +0 -0
  669. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_boundary.py +0 -0
  670. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_branches.py +0 -0
  671. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
  672. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
  673. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_decompose.py +0 -0
  674. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
  675. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
  676. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_fork.py +0 -0
  677. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_helpers.py +0 -0
  678. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_mongo.py +0 -0
  679. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_protocols.py +0 -0
  680. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_router.py +0 -0
  681. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_shape.py +0 -0
  682. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_sink.py +0 -0
  683. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_step.py +0 -0
  684. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
  685. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_table/common.py +0 -0
  686. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_table/config.py +0 -0
  687. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_with.py +0 -0
  688. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/refs.py +0 -0
  689. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/testing.py +0 -0
  690. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/__init__.py +0 -0
  691. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/agents.py +0 -0
  692. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/golden.py +0 -0
  693. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/http_harness.py +0 -0
  694. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/in_memory.py +0 -0
  695. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/repository_harness.py +0 -0
  696. {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/runner.py +0 -0
@@ -459,6 +459,85 @@
459
459
 
460
460
  ### core
461
461
 
462
+ - **core:** with no `LOOM_ENV` and no `environment=`, a process starts as
463
+ `production` and runs the deploy checks; an API without authentication now
464
+ fails at startup with `loom.rest.E001` until it configures
465
+ `app.rest.auth.jwt`, sets `app.rest.auth.custom: true` and passes an
466
+ `authenticator`, sets `LOOM_ENV=development`, or lists the id under
467
+ `checks.silenced`. An unknown or empty `LOOM_ENV` is a startup error.
468
+ - **core:** the logger's default changed from development to production: with
469
+ no explicit `renderer`/`colors`, logs render as JSON without colours unless
470
+ the process resolved `development` or `test`. `create_kernel`,
471
+ `bootstrap_app`, `ObservabilityRuntime.from_config`, `configure_logging`
472
+ and `configure_logging_from_values` take `environment=None` and resolve it
473
+ (`LOOM_ENV`, else production) when none is passed.
474
+ - **core:** the logger's own environment is removed:
475
+ `loom.core.logger.Environment`, `LoggerConfig.environment` and
476
+ `LogConfig.environment` are gone, and the logging functions take
477
+ `loom.core.environment.Environment`.
478
+ - **core:** configuration sections refuse keys they do not declare: the
479
+ logger and its handlers, `checks`, `app.rest` (with `auth`, `jwt`, `cors`
480
+ and `discovery`), the `observability` log, otel and prometheus structs and
481
+ `OtelConfig`, `sql`, `celery` and `jobs`, every ETL `storage` struct and
482
+ lineage, `kafka`, the bytewax runtime, streaming `mongo`, `dynamodb` and the
483
+ flow config. A leftover `observability.log.config.environment`, or any
484
+ typo there, is a `ConfigError`. `app`, `database`, `persistence` and the
485
+ top of `observability`, which several readers decode in part, still accept
486
+ keys another reader owns. `create_app` and `bootstrap_worker` no longer fall
487
+ back to the default `observability` section when it fails validation, and
488
+ `create_app` registers the in-process job service when the `celery`
489
+ section is absent (with a warning) or the Celery extra is not installed; a
490
+ `celery` section that fails validation now stops startup instead.
491
+ - **core:** a `LOOM__*` override sets one leaf value. A variable naming no
492
+ known section, with a malformed level, whose value is or holds a mapping,
493
+ whose target the files declare as a mapping or a list of mappings, naming
494
+ `config`, holding `${` however it is written, reaching inside an
495
+ interpolated key, failing to parse, or colliding with another variable
496
+ stops startup naming the variable, never the value. In production and
497
+ staging an override may set only an allowlisted key: loom's operational
498
+ keys (`loom.core.config.overrides.OVERRIDABLE`: log levels, Celery and
499
+ streaming worker counts and timeouts, SQL pool sizes and driver timeouts)
500
+ and the keys the reviewed files list under `config.overridable`. A
501
+ `config.overridable` entry starting with `*`, or inside `checks` or
502
+ `config`, stops every load. A placeholder in the `checks` section is a
503
+ `ConfigError`. A per-flow Prefect YAML is read without overrides.
504
+ `ConfigKey.LOGGER` and `ConfigKey.METRICS`, read by nothing, are removed.
505
+ - **core:** the SQL `max_execution_time`, `connect_timeout`,
506
+ `send_receive_timeout`, `pool_size` and `executor_threads`, the Celery
507
+ `runtime.shutdown_timeout_ms` and the streaming runtime's
508
+ `epoch_interval_ms` and `force_shutdown_timeout_ms` must be above zero; a
509
+ `0` fails when the section decodes.
510
+ - **core:** the `loom.core.checks` logger sets its own WARNING level, so a
511
+ parent level (`CRITICAL`, top-level or `named_levels.loom`) cannot hide a
512
+ deploy check's warning or the silenced ids; name `loom.core.checks` under
513
+ `named_levels` to quiet it. The handlers `configure_logging` attaches no
514
+ longer filter by level, so a named level below the top-level level takes
515
+ effect for stdlib loggers; structlog loggers, loom's own included, still
516
+ drop events below the top-level level.
517
+ - **core:** a consumer's test suite must set `LOOM_ENV=test` (loom's own
518
+ sets it in `tests/conftest.py`), or every application it builds starts as
519
+ production and runs the deploy checks.
520
+ - **core:** the migration locator now resolves `LOOM_ENV` (picking the
521
+ overlay of a config directory), applies the `LOOM__*` variables and puts
522
+ `app.code_path` on `sys.path` when the directory exists, as the
523
+ application does. `loom check --deploy` refuses an `app.code_path` that is
524
+ not a literal path.
525
+ - **core:** `ETLRunner` and `StreamingRunner` resolve the environment
526
+ (`LOOM_ENV`, else production): without one they log JSON and, built from a
527
+ whole configuration (a file, a directory, or a mapping for
528
+ `StreamingRunner.from_dict`), run the deploy checks; `ETLRunner.from_dict`
529
+ and `from_spark` receive no whole configuration and run none.
530
+ - **core:** `loom.core.locator.CONFIG_ENV_VAR` is replaced by
531
+ `loom.core.environment.CONFIG_VARIABLE`; `LOOM_CONFIG` may name a config
532
+ directory. `loom.prefect`'s `LOOM_ETL_CONFIG` alias is removed; use
533
+ `loom.core.environment.ETL_CONFIG_VARIABLE`. `app.code_path` is added to
534
+ `sys.path` only when the directory exists.
535
+ - **core:** a non-deployed environment logs one WARNING that the deploy
536
+ checks were skipped.
537
+ - **rest:** `create_app(authenticator=...)` requires
538
+ `app.rest.auth.custom: true`, `custom: true` requires an `authenticator`,
539
+ and `custom: true` beside `app.rest.auth.jwt` is refused; `loom.rest.E001`
540
+ passes on `custom: true`.
462
541
  - **core:** `Rule.check(..., via=fn)` takes the violation from `fn`: a `str`
463
542
  (the message) or a `RuleViolation` fails the rule, `None` passes it. A `bool`
464
543
  or any other result raises `TypeError` naming the field, instead of `True`
@@ -602,6 +681,37 @@
602
681
 
603
682
  ### rest
604
683
 
684
+ - **rest:** a `QuerySpec` route filters and sorts only on the columns it
685
+ declares. Before, a client could filter or sort on any field the repository
686
+ could resolve. Now a filter on an undeclared column answers
687
+ `400 unsupported_query` naming the field, and so does a sort on one, with the
688
+ same answer whether or not the column exists. The primary key, which the
689
+ route orders by when the client names no sort, needs no declaration.
690
+ Declare `filterable` and `sortable` on the interface (its auto-CRUD `list`
691
+ route included) or on a route, which overrides it, as field references or
692
+ column names:
693
+
694
+ ```python
695
+ class OrderRestInterface(RestInterface[Order]):
696
+ prefix = "/orders"
697
+ auto = True
698
+ filterable = (F(Order).status, F(Order).total)
699
+ sortable = (F(Order).created_at,)
700
+ ```
701
+
702
+ In `app.rest.interfaces` both take column names (`[status, total]`).
703
+ `ALL` (`all` in YAML) keeps every scalar column and logs a warning naming
704
+ the route at startup. Only scalar columns of the use case's own model
705
+ (`UseCase[Model, ...]`) qualify. A related model's column (`warehouse.code`)
706
+ is refused, and so are JSON, array and text-search columns; lists, dicts
707
+ and structs, and an `Enum` or `Literal` declared without a column type, are
708
+ JSON. `InterfaceCompilationError` names the route and the field. It is also
709
+ raised for a declaration on a use case with no model, and for a route-level
710
+ declaration on a route without a `QuerySpec`; an inherited one is ignored.
711
+ `exists` and `not_exists` answer `400 unsupported_query`, and so do `like`
712
+ and `ilike` on a column that is not `str`. The repository's
713
+ `allowed_filter_fields` is unchanged: programmatic callers are not
714
+ restricted.
605
715
  - **rest:** every route now resolves its request parameters and decodes its
606
716
  body before the use case is built, so a request refused at that point
607
717
  never runs the use case's constructor.
@@ -633,6 +743,20 @@
633
743
 
634
744
  ### prefect
635
745
 
746
+ - **prefect:** `FlowCtx.environment` is removed; nothing read it.
747
+ - **prefect:** the flow parameter `env` and the keys of a flow YAML's
748
+ `environments` block are loom environments (`production`, `staging`,
749
+ `development`, `test`); `prod`, `dev`, `local` or any other key or value is
750
+ a `ConfigError`. A run resolves the worker's environment (`LOOM_ENV`, else
751
+ production); `env` defaults to `None` and only confirms it, so a run whose
752
+ `env` differs fails before anything runs. The run hands the environment to
753
+ the runner, which takes its logger defaults from it and runs the deploy
754
+ checks when deployed; notifications report it. `deploy_flow` and
755
+ `discover_and_deploy_etls` take an optional `env` resolved the same way and
756
+ record it as the deployment's `env` parameter, so a deployment run on a
757
+ worker in another environment fails.
758
+ - **prefect:** the storage configuration of a flow run may be a config
759
+ directory.
636
760
  - **prefect:** a placeholder counts from the run's scheduled start instead of
637
761
  the wall clock. `${today-1d}`, `${yesterday}` and `${now±N}` counted from
638
762
  `datetime.now()` inside the flow, so a queued run that started after
@@ -767,6 +891,60 @@
767
891
 
768
892
  ### core
769
893
 
894
+ - **core:** one environment selector and deploy checks (ADR 0005). loom had
895
+ two unconnected notions of environment (the logger's `dev`/`prod`, where an
896
+ unknown value meant `dev`, and `FlowCtx.environment`) and nothing checked a
897
+ deployed configuration. `loom.core.environment` now holds
898
+ `Environment` (`production`, `staging`, `development`, `test`) and
899
+ `resolve_environment`: the explicit argument, else `LOOM_ENV`, else
900
+ `production`; an unknown or empty value raises `ConfigError`. REST
901
+ `create_app`, Celery `create_app` and `bootstrap_worker` take
902
+ `environment=` and `config_dir=`, which loads `base.yaml` then
903
+ `<environment>.yaml` when present; explicit file lists keep working, one
904
+ form or the other. `create_kernel(environment=...)` registers the
905
+ environment in the container, so a use case can inject `Environment`.
906
+ `loom.core.checks` adds deploy checks with stable ids
907
+ (`@deploy_check("<area>.<E|W><nnn>")`), run at startup in production and
908
+ staging: `E` fails startup with `DeployCheckError`, `W` logs a warning, and
909
+ `checks.silenced: [ids]` silences by id with a startup warning naming them.
910
+ Initial checks: `loom.rest.E001` (neither a literal `app.rest.auth.jwt`
911
+ mapping nor the literal `app.rest.auth.custom: true`), `loom.rest.W001` (docs, redoc or OpenAPI
912
+ URL not `null`), `loom.logger.W001` (`console` renderer); they read keys as
913
+ written (`ConfigContext.raw`) and resolve no placeholder. Processes serving
914
+ no HTTP skip the `loom.rest` checks. `loom check --deploy [--env X]
915
+ [--skip AREA] <config>` runs them in CI without starting the application
916
+ and prints the areas it skipped.
917
+ - **core:** one place tells every loom process its environment and
918
+ configuration (ADR 0005). `LOOM__SECTION__KEY` variables override any
919
+ configuration key as the last layer (code defaults < `base.yaml` <
920
+ `<LOOM_ENV>.yaml` < `LOOM__*`, allowlisted keys only in production and
921
+ staging), merged as an OmegaConf dotlist; levels
922
+ match declared keys case-insensitively, a first level naming no known
923
+ section is a `ConfigError` naming the variable, values are parsed literals
924
+ (no `${` anywhere in them), an override sets one leaf, and one WARNING
925
+ line names the overridden keys without their values.
926
+ `loom.core.config.overrides.load_application_config` is the one loader
927
+ behind REST and Celery `create_app`, `bootstrap_worker`,
928
+ `loom check --deploy`, `ETLRunner.from_yaml`, `StreamingRunner.from_yaml`,
929
+ the migration locator and `load_kafka_settings`; a per-flow Prefect YAML is
930
+ a flow definition and is read without them. Deploy checks see the final configuration. `ETLRunner`,
931
+ `StreamingRunner` and the migration locator accept a config directory as
932
+ the factories do. They take `environment=`, take their logger defaults from
933
+ it and run the deploy checks when deployed, like the Prefect flows through
934
+ them; a Prefect run's `env` only confirms the worker's environment.
935
+ Only `loom.core.environment` names, reads or sets `LOOM_*` variables.
936
+ `checks.modules` lists the modules registering an
937
+ application's own checks, imported before every run, at startup and in
938
+ `loom check --deploy` (which puts `app.code_path` on the import path as
939
+ `create_app` does). `app.rest.auth.custom: true` declares an authenticator
940
+ passed in code, so `loom.rest.E001` reads the same answer in CI and at
941
+ startup. `parse_environment` validates a value naming an environment.
942
+ - **core:** the SQLAlchemy query compiler converts a filter value, and each
943
+ `in` item, as the repository converts a value it writes
944
+ (`loom.core.repository.sqlalchemy.values.to_column_value`, now shared by
945
+ both): an `Enum` member is bound as its value, a JSON column's value is
946
+ reduced to builtins. A plain `Enum` member as the value of a filter on a
947
+ string column failed to bind.
770
948
  - **core:** a `BoundaryValidationError` no longer echoes the rejected value
771
949
  (#347). msgspec's `Invalid enum value 'x'` (an `Enum`, `IntEnum` or `Literal`
772
950
  field or dict key) and `Invalid value 'x'` (a tagged-union tag) become
@@ -953,6 +1131,29 @@
953
1131
 
954
1132
  ### rest
955
1133
 
1134
+ - **rest:** `?sort=` accepted any column. A cursor page put the sort
1135
+ column's raw value of its last row in `nextCursor` (base64 JSON), so any
1136
+ column, a secret one included, could be read through it, and a forged
1137
+ cursor could range-probe it. Offset pages leaked its order, and an unknown
1138
+ column answered `400 unsupported_query` (`Unknown filter field path`) while
1139
+ a known one answered `200`, so the model's columns could be enumerated. A
1140
+ route now sorts only by its declared `sortable` columns and its primary
1141
+ key, so a cursor carries only those values.
1142
+ - **rest:** a `page` whose offset, `(page - 1) * limit`, exceeds the largest
1143
+ signed 64-bit integer answers `400 query_validation` on `page` before any
1144
+ query runs.
1145
+ - **rest:** a `QuerySpec` filter value was typed by its spelling: `true` and
1146
+ `false` became booleans, text with a `.` a float and digits an integer,
1147
+ whatever the filtered field declared. `?code=0123` on a `str` field compared
1148
+ against `123`, and on Postgres a number bound to a text column answered
1149
+ `500`. Values of `eq`, `ne`, `gt`, `gte`, `lt`, `lte` and each item of `in`
1150
+ are now converted by the type of the declared filterable field, with the
1151
+ strict grammar of `Query()`: a `str` field keeps the text as sent, a
1152
+ boolean accepts only `true` or `false`, an `Enum` or `Literal` only its
1153
+ values, and a value its field's type refuses answers `400 query_validation`
1154
+ with `violations` naming the field. The field's constraints
1155
+ (`msgspec.Meta`) do not apply to a filter value, so `rank__gt=0` is valid
1156
+ on a column declared `ge=1`. `like` and `ilike` keep their pattern as text.
956
1157
  - **rest:** the OpenAPI `limit` parameter of a `QuerySpec` route published
957
1158
  `maximum: 1000` and `default: 50` whatever `RestApiDefaults.max_limit` said,
958
1159
  while the router clamped `?limit=` to `max_limit`. The schema now publishes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: loom-kernel
3
- Version: 2.22.3
3
+ Version: 4.0.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Classifier: Programming Language :: Python :: 3
@@ -484,6 +484,10 @@ from loom.rest.fastapi.auto import create_app
484
484
  app = create_app("config/api.yaml")
485
485
  ```
486
486
 
487
+ Run it with `LOOM_ENV=development`: an unset `LOOM_ENV` means production, where
488
+ the deploy checks refuse an API that authenticates nobody (`loom.rest.E001`).
489
+ See [Environments and deploy checks](docs/getting-started/environments.md).
490
+
487
491
  For larger projects, use `mode: manifest` and a manifest module:
488
492
 
489
493
  ```python
@@ -360,6 +360,10 @@ from loom.rest.fastapi.auto import create_app
360
360
  app = create_app("config/api.yaml")
361
361
  ```
362
362
 
363
+ Run it with `LOOM_ENV=development`: an unset `LOOM_ENV` means production, where
364
+ the deploy checks refuse an API that authenticates nobody (`loom.rest.E001`).
365
+ See [Environments and deploy checks](docs/getting-started/environments.md).
366
+
363
367
  For larger projects, use `mode: manifest` and a manifest module:
364
368
 
365
369
  ```python
@@ -13,11 +13,14 @@ from loom.core.di.container import LoomContainer
13
13
  if TYPE_CHECKING:
14
14
  from loom.core.config import ConfigResolver
15
15
  from loom.core.engine.metrics import MetricsAdapter
16
+ from loom.core.environment import Environment
16
17
  from loom.core.job.job import Job
17
18
 
18
19
 
19
20
  def create_app(
20
21
  *config_paths: str,
22
+ config_dir: str | None = None,
23
+ environment: Environment | str | None = None,
21
24
  jobs: Sequence[type[Job[Any]]] = (),
22
25
  callbacks: Sequence[type[Any]] = (),
23
26
  modules: Sequence[Callable[[LoomContainer], None]] = (),
@@ -27,7 +30,12 @@ def create_app(
27
30
  """Create a Celery app with all Loom job tasks registered.
28
31
 
29
32
  Args:
30
- *config_paths: One or more YAML config files merged left-to-right.
33
+ *config_paths: YAML config files merged left-to-right. Mutually
34
+ exclusive with *config_dir*.
35
+ config_dir: Directory holding ``base.yaml`` and the per-environment
36
+ overlays; ``<environment>.yaml`` loads after the base when present.
37
+ environment: Environment of the worker; overrides ``LOOM_ENV``, which
38
+ defaults to production when unset.
31
39
  jobs: Concrete ``Job`` subclasses to register as Celery tasks.
32
40
  Optional when ``app.discovery`` (modules/manifest) is configured.
33
41
  callbacks: Optional callback classes for success/failure hooks.
@@ -42,6 +50,8 @@ def create_app(
42
50
  """
43
51
  result = bootstrap_worker(
44
52
  *config_paths,
53
+ config_dir=config_dir,
54
+ environment=environment,
45
55
  jobs=jobs,
46
56
  callbacks=callbacks,
47
57
  modules=modules,
@@ -83,6 +83,7 @@ from loom.celery.runner import (
83
83
  from loom.core.async_bridge import build_backend_options
84
84
  from loom.core.bootstrap import KernelRuntime, create_kernel
85
85
  from loom.core.cache.wiring import cache_module_for
86
+ from loom.core.checks import REST_CHECKS, enforce_deploy_checks
86
87
  from loom.core.config import (
87
88
  ConfigContext,
88
89
  ConfigKey,
@@ -90,10 +91,12 @@ from loom.core.config import (
90
91
  with_default_resolvers,
91
92
  )
92
93
  from loom.core.config.errors import ConfigError
94
+ from loom.core.config.overrides import load_application_config
93
95
  from loom.core.di.container import LoomContainer
94
96
  from loom.core.discovery._utils import collect_from_modules, import_modules
95
97
  from loom.core.engine.compilable import Compilable
96
98
  from loom.core.engine.metrics import MetricsAdapter
99
+ from loom.core.environment import Environment, resolve_environment, select_config_paths
97
100
  from loom.core.job.job import Job
98
101
  from loom.core.model import BaseModel
99
102
  from loom.core.observability.config import ObservabilityConfig
@@ -666,14 +669,18 @@ def _compile_models(
666
669
 
667
670
  def _build_observability_runtime(
668
671
  ctx: ConfigContext | Mapping[str, Any],
672
+ environment: Environment = Environment.PRODUCTION,
669
673
  ) -> ObservabilityRuntime:
670
- """Build the shared observability runtime from top-level config."""
674
+ """Build the shared observability runtime from top-level config.
675
+
676
+ Defaults apply only when the section is absent; one that fails validation
677
+ stops the worker instead of silently dropping its settings.
678
+ """
671
679
  config = _ensure_config_context(ctx)
672
- try:
673
- observability_cfg = config.section(ConfigKey.OBSERVABILITY, ObservabilityConfig)
674
- except ConfigError:
675
- observability_cfg = ObservabilityConfig()
676
- return ObservabilityRuntime.from_config(observability_cfg)
680
+ observability_cfg = config.section_or_default(
681
+ ConfigKey.OBSERVABILITY, ObservabilityConfig, ObservabilityConfig()
682
+ )
683
+ return ObservabilityRuntime.from_config(observability_cfg, environment=environment)
677
684
 
678
685
 
679
686
  def _compile_db_layer(
@@ -835,6 +842,8 @@ def _reject_mcp_markers(
835
842
 
836
843
  def bootstrap_worker(
837
844
  *config_paths: str,
845
+ config_dir: str | None = None,
846
+ environment: Environment | str | None = None,
838
847
  jobs: Sequence[type[Job[Any]]] = (),
839
848
  use_cases: Sequence[type[Compilable]] = (),
840
849
  interfaces: Sequence[type[Any]] = (),
@@ -845,9 +854,15 @@ def bootstrap_worker(
845
854
  ) -> WorkerBootstrapResult:
846
855
  """Bootstrap a Celery worker process and register all Job tasks.
847
856
 
848
- Loads configuration from ``config_paths``, compiles all ``Job``
849
- subclasses, registers Celery tasks, and connects worker lifecycle
850
- signals for per-process async bridge management.
857
+ Resolves the environment once (*environment*, else ``LOOM_ENV``, else
858
+ production; see :mod:`loom.core.environment`), loads configuration from
859
+ ``config_dir`` or ``config_paths``, compiles all ``Job`` subclasses,
860
+ registers Celery tasks, and connects worker lifecycle signals for
861
+ per-process async bridge management.
862
+
863
+ In production and staging the deploy checks run (see
864
+ :mod:`loom.core.checks`), except the ``loom.rest`` ones: a worker serves
865
+ no HTTP. The environment is registered in the container.
851
866
 
852
867
  This function is **independent** of
853
868
  :func:`~loom.core.bootstrap.bootstrap.bootstrap_app` — it targets the
@@ -865,9 +880,14 @@ def bootstrap_worker(
865
880
  persistence.
866
881
 
867
882
  Args:
868
- *config_paths: One or more paths to YAML configuration files.
869
- Files are merged left-to-right. Later files override earlier
870
- ones.
883
+ *config_paths: Paths to YAML configuration files, merged
884
+ left-to-right; later files override earlier ones. Mutually
885
+ exclusive with *config_dir*.
886
+ config_dir: Local directory holding ``base.yaml`` and the
887
+ per-environment overlays: ``base.yaml`` loads first, then
888
+ ``<environment>.yaml`` when present. Either way the
889
+ ``LOOM__SECTION__KEY`` variables merge last.
890
+ environment: Environment of the worker; overrides ``LOOM_ENV``.
871
891
  jobs: Concrete ``Job`` subclasses to compile/register. When
872
892
  omitted, jobs are discovered from ``app.discovery`` using
873
893
  mode ``modules`` or ``manifest``.
@@ -899,8 +919,11 @@ def bootstrap_worker(
899
919
  configured Celery application.
900
920
 
901
921
  Raises:
902
- ConfigError: If a required configuration section is missing or
903
- fails validation.
922
+ ConfigError: If neither or both of *config_paths* and *config_dir*
923
+ are given, the environment is unknown, or a required
924
+ configuration section is missing or fails validation.
925
+ DeployCheckError: When a deploy check of level error fails in
926
+ production or staging.
904
927
  RuntimeError: If no ``app.discovery`` config is provided and no
905
928
  ``jobs`` are declared, or if discovery finds no ``Job`` classes.
906
929
 
@@ -915,10 +938,17 @@ def bootstrap_worker(
915
938
  )
916
939
  result.celery_app.start()
917
940
  """
918
- ctx = ConfigContext.from_yaml(*config_paths, resolvers=with_default_resolvers(resolvers))
941
+ resolved_environment = resolve_environment(environment)
942
+ paths = select_config_paths(
943
+ config_paths, config_dir, resolved_environment, caller="bootstrap_worker"
944
+ )
945
+ ctx = load_application_config(
946
+ *paths, resolvers=with_default_resolvers(resolvers), environment=resolved_environment
947
+ )
919
948
  app_cfg = ctx.section_optional(ConfigKey.APP, _WorkerAppConfig) or _WorkerAppConfig()
920
949
  celery_cfg = ctx.section(ConfigKey.CELERY, CeleryConfig)
921
- observability_runtime = _build_observability_runtime(ctx)
950
+ observability_runtime = _build_observability_runtime(ctx, resolved_environment)
951
+ enforce_deploy_checks(ctx, resolved_environment, skip=(REST_CHECKS,))
922
952
  async_runtime = _build_async_runtime(celery_cfg.runtime)
923
953
 
924
954
  resolved = _resolve_compilables_and_jobs(ctx, jobs, use_cases)
@@ -951,6 +981,7 @@ def bootstrap_worker(
951
981
  modules=runtime_modules,
952
982
  metrics=metrics,
953
983
  uow_factory=uow_factory,
984
+ environment=resolved_environment,
954
985
  )
955
986
  _reject_agent_markers(resolved.compilables, kernel)
956
987
  _reject_mcp_markers(resolved.compilables, kernel)
@@ -37,12 +37,13 @@ from celery import Celery # type: ignore[import-untyped]
37
37
  from kombu import Queue # type: ignore[import-untyped]
38
38
 
39
39
  from loom.core.model import LoomFrozenStruct
40
+ from loom.core.model.types import PositiveInt
40
41
 
41
42
  if TYPE_CHECKING:
42
43
  from loom.core.job.job import Job
43
44
 
44
45
 
45
- class CeleryRuntimeConfig(LoomFrozenStruct, frozen=True, kw_only=True):
46
+ class CeleryRuntimeConfig(LoomFrozenStruct, frozen=True, kw_only=True, forbid_unknown_fields=True):
46
47
  """Async bridge settings for a Celery worker process.
47
48
 
48
49
  Attributes:
@@ -51,15 +52,16 @@ class CeleryRuntimeConfig(LoomFrozenStruct, frozen=True, kw_only=True):
51
52
  use_uvloop: When ``True`` and the backend is ``"asyncio"``, the worker
52
53
  uses uvloop on supported platforms.
53
54
  shutdown_timeout_ms: Maximum milliseconds to wait for in-flight async
54
- work during worker shutdown. ``None`` waits indefinitely.
55
+ work during worker shutdown, above zero. ``None`` waits
56
+ indefinitely.
55
57
  """
56
58
 
57
59
  backend: Literal["asyncio", "trio"] = "asyncio"
58
60
  use_uvloop: bool = False
59
- shutdown_timeout_ms: int | None = None
61
+ shutdown_timeout_ms: PositiveInt | None = None
60
62
 
61
63
 
62
- class CeleryConfig(LoomFrozenStruct, frozen=True, kw_only=True):
64
+ class CeleryConfig(LoomFrozenStruct, frozen=True, kw_only=True, forbid_unknown_fields=True):
63
65
  """Broker and worker settings for the Celery application.
64
66
 
65
67
  Attributes:
@@ -109,7 +111,7 @@ class CeleryConfig(LoomFrozenStruct, frozen=True, kw_only=True):
109
111
  runtime: CeleryRuntimeConfig = msgspec.field(default_factory=CeleryRuntimeConfig)
110
112
 
111
113
 
112
- class JobConfig(LoomFrozenStruct, frozen=True, kw_only=True):
114
+ class JobConfig(LoomFrozenStruct, frozen=True, kw_only=True, forbid_unknown_fields=True):
113
115
  """Per-job routing and execution overrides applied at bootstrap.
114
116
 
115
117
  Fields set to ``None`` leave the corresponding ClassVar on the
@@ -4,7 +4,9 @@ from __future__ import annotations
4
4
 
5
5
  import typer
6
6
 
7
+ from loom.cli.check import check
7
8
  from loom.cli.schema import schema_app
8
9
 
9
- app = typer.Typer(no_args_is_help=True, help="Operate the database side of a loom application.")
10
+ app = typer.Typer(no_args_is_help=True, help="Operate a loom application.")
10
11
  app.add_typer(schema_app, name="schema")
12
+ app.command("check")(check)
@@ -0,0 +1,105 @@
1
+ """``loom check --deploy``: run the deploy checks without starting the application.
2
+
3
+ Meant for CI: it loads the configuration the application would load, runs
4
+ every deploy check whatever the environment, prints each finding with its id
5
+ and hint, and exits ``1`` when an error remains. loom's checks read keys as
6
+ written and resolve no placeholder; the configuration loads with loom's
7
+ default resolvers, so a ``${secrets:...}`` value no check reads is left alone.
8
+
9
+ The command cannot tell which kind of process a configuration is for: a REST
10
+ application may declare ``celery`` for its job service and a worker may share
11
+ ``app.rest``. ``--skip loom.rest`` (repeatable, any id or area) leaves out
12
+ what the process does not run, as the worker and the runners do at startup.
13
+
14
+ ``app.code_path`` (``src`` by default, relative to the first file) joins the
15
+ import path as ``create_app`` adds it, so the modules of ``checks.modules``
16
+ import here as they do at startup.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import importlib
22
+ import importlib.util
23
+ from pathlib import Path
24
+ from typing import Annotated
25
+
26
+ import typer
27
+
28
+ from loom.core.checks import DeployReport, run_deploy_checks
29
+ from loom.core.config import ConfigContext, with_default_resolvers
30
+ from loom.core.config.errors import ConfigError
31
+ from loom.core.config.overrides import load_application_config
32
+ from loom.core.environment import Environment, resolve_environment, select_config_paths
33
+ from loom.core.locator import DEFAULT_CODE_PATH, add_code_path
34
+
35
+
36
+ def check(
37
+ config: Annotated[
38
+ list[Path],
39
+ typer.Argument(help="A config directory (base.yaml plus overlays) or YAML files."),
40
+ ],
41
+ deploy: Annotated[bool, typer.Option("--deploy", help="Run the deploy checks.")] = False,
42
+ env: Annotated[
43
+ str | None,
44
+ typer.Option("--env", help="Environment picking the overlay; defaults to LOOM_ENV."),
45
+ ] = None,
46
+ skip: Annotated[
47
+ list[str] | None,
48
+ typer.Option("--skip", help="A check id or area to leave out, e.g. loom.rest; repeatable."),
49
+ ] = None,
50
+ ) -> None:
51
+ """Run the deploy checks against the configuration, for CI."""
52
+ if not deploy:
53
+ typer.echo("only deploy checks exist: run 'loom check --deploy <config>'.", err=True)
54
+ raise typer.Exit(2)
55
+ _load_check_packages()
56
+ try:
57
+ environment = resolve_environment(env)
58
+ paths = _config_paths(config, environment)
59
+ context = load_application_config(
60
+ *paths, resolvers=with_default_resolvers(()), environment=environment
61
+ )
62
+ _add_code_path(context, Path(paths[0]).resolve().parent)
63
+ report = run_deploy_checks(context, skip=tuple(skip or ()))
64
+ except ConfigError as exc:
65
+ typer.echo(str(exc), err=True)
66
+ raise typer.Exit(1) from exc
67
+ _print(report, environment, tuple(skip or ()))
68
+ if report.errors:
69
+ raise typer.Exit(1)
70
+
71
+
72
+ def _load_check_packages() -> None:
73
+ """Import the packages registering loom's checks; the REST ones need the rest extra."""
74
+ importlib.import_module("loom.core.logger")
75
+ if importlib.util.find_spec("fastapi") is not None:
76
+ importlib.import_module("loom.rest")
77
+
78
+
79
+ def _add_code_path(context: ConfigContext, config_dir: Path) -> None:
80
+ raw = context.raw("app.code_path", DEFAULT_CODE_PATH)
81
+ if not isinstance(raw, str) or "${" in raw:
82
+ raise ConfigError(
83
+ "app.code_path must be a literal path for loom check: a placeholder or a "
84
+ "non-string value cannot name the directory its check modules import from"
85
+ )
86
+ add_code_path(raw, config_dir)
87
+
88
+
89
+ def _config_paths(config: list[Path], environment: Environment) -> tuple[str, ...]:
90
+ directory = config[0] if len(config) == 1 and config[0].is_dir() else None
91
+ if directory is None and any(path.is_dir() for path in config):
92
+ raise ConfigError("pass one config directory or YAML files, not both")
93
+ files = () if directory is not None else tuple(str(path) for path in config)
94
+ return select_config_paths(files, directory, environment, caller="loom check")
95
+
96
+
97
+ def _print(report: DeployReport, environment: Environment, skipped: tuple[str, ...]) -> None:
98
+ typer.echo(f"environment: {environment}")
99
+ if skipped:
100
+ typer.echo(f"skipped: {', '.join(skipped)}")
101
+ if report.silenced:
102
+ typer.echo(f"silenced: {', '.join(report.silenced)}")
103
+ for result in report.results:
104
+ typer.echo(f"{result.level.upper()} {result.describe()}")
105
+ typer.echo(f"{len(report.errors)} error(s), {len(report.warnings)} warning(s)")
@@ -33,6 +33,7 @@ from loom.core.engine.compilable import Compilable
33
33
  from loom.core.engine.compiler import UseCaseCompiler
34
34
  from loom.core.engine.executor import RuntimeExecutor
35
35
  from loom.core.engine.metrics import MetricsAdapter
36
+ from loom.core.environment import Environment, resolve_environment
36
37
  from loom.core.logger import LoggerPort, get_logger
37
38
  from loom.core.use_case.factory import UseCaseFactory
38
39
 
@@ -77,6 +78,7 @@ def bootstrap_app(
77
78
  modules: Sequence[Callable[[LoomContainer], None]] = (),
78
79
  logger: LoggerPort | None = None,
79
80
  metrics: MetricsAdapter | None = None,
81
+ environment: Environment | str | None = None,
80
82
  ) -> BootstrapResult:
81
83
  """Run the deterministic Loom bootstrap pipeline.
82
84
 
@@ -97,6 +99,11 @@ def bootstrap_app(
97
99
  Executed in declaration order before compilation.
98
100
  logger: Optional logger. Falls back to the framework default.
99
101
  metrics: Optional metrics adapter passed to the compiler.
102
+ environment: Environment of the application, resolved like
103
+ :func:`~loom.core.environment.resolve_environment` (``LOOM_ENV``,
104
+ else production) when ``None``. Registered at ``APPLICATION``
105
+ scope with the configuration, before the modules run, so a
106
+ module's service can resolve it.
100
107
 
101
108
  Returns:
102
109
  :class:`BootstrapResult` with container, compiler, and factory.
@@ -117,12 +124,14 @@ def bootstrap_app(
117
124
  app = create_fastapi_app(result, RouteSources(python=[OrderRestInterface]))
118
125
  """
119
126
  _logger = logger or get_logger("loom.bootstrap")
127
+ resolved_environment = resolve_environment(environment)
120
128
 
121
129
  try:
122
130
  # Step 1 — Container + config binding
123
131
  _logger.info("[BOOT] Initialising DI container")
124
132
  container = LoomContainer()
125
133
  container.register(type(config), lambda: config, scope=Scope.APPLICATION)
134
+ container.register(Environment, lambda: resolved_environment, scope=Scope.APPLICATION)
126
135
 
127
136
  # Step 2 — User module bindings
128
137
  for module in modules: