loom-kernel 10.2.0__tar.gz → 10.3.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.
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/CHANGELOG.md +36 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/PKG-INFO +1 -1
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/cli/check.py +1 -0
- loom_kernel-10.3.0/src/loom/cli/schema.py +243 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/backend/sqlalchemy.py +40 -2
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/environment.py +16 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/identity/__init__.py +8 -1
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/identity/identity.py +4 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/locator.py +37 -17
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/__init__.py +3 -0
- loom_kernel-10.3.0/src/loom/core/model/audited.py +75 -0
- loom_kernel-10.3.0/src/loom/core/persistence/audit_checks.py +51 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/persistence/database.py +15 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/backend.py +47 -6
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +54 -6
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/model.py +20 -3
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +2 -1
- loom_kernel-10.3.0/src/loom/core/repository/sqlalchemy/rls/audit.py +176 -0
- loom_kernel-10.3.0/src/loom/core/repository/sqlalchemy/rls/audit_verify.py +177 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/config.py +26 -2
- loom_kernel-10.3.0/src/loom/core/repository/sqlalchemy/rls/findings.py +26 -0
- loom_kernel-10.3.0/src/loom/core/repository/sqlalchemy/rls/guard/0003.sql +530 -0
- loom_kernel-10.3.0/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +237 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +157 -5
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +31 -3
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +12 -3
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +117 -59
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/auth/jwt.py +15 -1
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/functions.py +39 -12
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/handler.py +44 -13
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/triggers/__init__.py +7 -1
- loom_kernel-10.3.0/src/loom/serverless/aws/lambda_/triggers/eventbridge.py +42 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/triggers/s3.py +8 -1
- loom_kernel-10.2.0/src/loom/cli/schema.py +0 -107
- loom_kernel-10.2.0/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -150
- loom_kernel-10.2.0/src/loom/serverless/aws/lambda_/triggers/eventbridge.py +0 -22
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/.gitignore +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/LICENSE +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/README.md +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/pyproject.toml +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/_concurrency.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/_filters.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/_paths.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/_roles.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/_startup.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/_transport.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/_usecase.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/a2a/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/a2a/_binding.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/a2a/_handlers.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/a2a/_rpc.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/a2a/card.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/a2a/events.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/a2a/server.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/abc.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/bootstrap.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/_compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/_fingerprint.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/_plan.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_output.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/compiler/phases/_state.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/declarative/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/declarative/_envelope.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/declarative/_schema.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/declarative/_v1.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/describe.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/etl/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/etl/_batch.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/etl/_columns.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/etl/_frames.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/etl/_ledger.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/etl/_runner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/etl/_validation.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/fastapi/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/fastapi/endpoints.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/fastapi/response.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/fastapi/streaming.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/inference.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/pricing.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/remote_auth.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_bounded.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_chain.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_conversation.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_grants.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_handle.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_health.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_hooks.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_limits.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/runtime/_mcp.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/validate/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/ai/validate/__main__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/_discovery.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/adapter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/auto.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/bootstrap.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/cli/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/cli/app.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/cli/deploy.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/_ai.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/_jobs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/_reserved.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/_sql.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/application.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/build.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/host.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/recipe.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/resources.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/composition/source.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/_async.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/async_bridge.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/authz/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/authz/_decide.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/authz/_grants.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/authz/_roles.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/authz/_scope.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/authz/elevation.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/authz/product.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/backend/scoped_ddl.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/_batching.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/_single_flight.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/calls.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/memory.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/result_codec.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/cache/wiring.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/checks.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/_includes.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/_interpolations.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/_resolver_utils.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/aws.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/binder.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/checks.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/configurable.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/context.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/convert.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/keys.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/observability.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/overrides.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/resolver.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/retired.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/secrets.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/config/ssm.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/_base.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/aws/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/aws/client.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/aws/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/aws/loader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/clickhouse/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/clickhouse/client.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/clickhouse/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/clickhouse/loader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/mongo/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/mongo/client.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/mongo/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/mongo/loader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/connections/relational.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/worker.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/discovery/worker_manifest.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/engine/post_commit.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/errors/auth.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/errors/base.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/errors/domain.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/errors/jobs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/errors/model.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/errors/stores.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/expr/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/expr/eval.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/expr/nodes.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/expr/refs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/identity/context.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/identity/issuer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/identity/wire.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/introspection/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/introspection/base.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/introspection/describe.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/envelope.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/outcome.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/router.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/run.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/logger/checks.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/logger/context.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/_json_schema.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/_loom_type.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/convert.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/introspection.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/partition.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/privilege.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/redaction.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/scoped.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/types.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/event.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/observer/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/observer/noop.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/observer/otel.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/observer/structlog.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/otel_ids.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/protocol.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/runtime.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/span.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/observability/topology.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/persistence/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/persistence/abc.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/persistence/elevation.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/persistence/none.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/persistence/profile.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/persistence/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/persistence/stores.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/plugins/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/plugins/entrypoints.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/plugins/optional.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/abc/checks.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/abc/cursor.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/abc/session_scope.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/dynamodb/backend.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mongo/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mongo/backend.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mongo/ids.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mongo/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mongo/repository.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mongo/uow.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mongo/values.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/_pool_metrics.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/repository/sqlalchemy/values.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/routing/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/routing/ref.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/routing/resolver.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/runner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/schema/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/schema/schema_mode.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/schema_names.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/abc/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/abc/contracts.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/abc/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/caller_bound.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/loader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/roles.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/sql/service.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/symbols.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/uow/alone.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/uow/coordinator.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/uow/scope.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/agent_markers.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/joined.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/mcp_markers.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/outcome.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/_uri.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_format_registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_historify/_common.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_historify/_log.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_merge.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_path_template.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_predicate.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/_write_policy.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_frame.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_historify.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_reader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_schema.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/_writer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/polars/provider.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/spark/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/spark/_historify.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/spark/_reader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/spark/_schema.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/spark/_writer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/backends/spark/provider.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/_backends/_memory.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/_options.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/_paths.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/_scope.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/checkpoint/_store.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_binding.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_filter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_plan.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_validators.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_validators_agents.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_validators_config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/compiler/_validators_step.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/_format.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/_read_options.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/_utils.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/_with_agent.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/_write_options.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/expr/_params.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/source/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/source/_from.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/source/_specs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_client.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_file.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_into.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_table.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/declarative/target/_temp.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/executor/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/executor/_agents.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/executor/_dispatcher.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/executor/_executor.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/_clickhouse_connection.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/_registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_mongo.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/sources/_serialization.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/targets/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/lineage/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/lineage/_config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/lineage/_observer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/lineage/_records.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/maintenance/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/maintenance/_builder.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/maintenance/_ops.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/maintenance/_protocol.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/maintenance/_runner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/maintenance/_step.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/_generics.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/_params.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/_process.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/_sql.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/_step.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/_step_client.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runner/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runner/_agents.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runner/_providers.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runner/_wiring.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runner/config_loader.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runner/core.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runner/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runtime/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runtime/_config_values.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/runtime/contracts.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/schema/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/schema/_contract.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/schema/_schema.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/storage/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/storage/_config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/storage/_file_locator.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/storage/_locator.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/storage/routing.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/testing/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/testing/_delta.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/testing/_result.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/testing/_runners.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/testing/_scenario.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/testing/_stubs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/etl/testing/spark.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/jobs/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/jobs/aws/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/jobs/aws/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/jobs/aws/sqs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/_async.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/_config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/_ctx.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/_flow_yaml.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/_meta.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/_placeholders.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/_summary.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/deploy/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/deploy/_discovery.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/deploy/_schedule.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/deploy/_yaml_etls.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/deploy/entrypoint.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_assemble.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_backfill.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_body.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_common.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_factory.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_hooks.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_maintenance.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_params.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_run_name.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_runtime.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_signature.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/flow/_stages.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/manifest/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/manifest/_model.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/manifest/_s3.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/manifest/_store.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/notify/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/notify/_event.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/notify/_factory.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/notify/_format.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/notify/_port.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/notify/_slack.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/notify/_sns.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/observer/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/observer/_flow.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/observer/_manifest.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prefect/observer/_task_run.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prometheus/_instruments.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prometheus/db_pool.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prometheus/kafka.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prometheus/lifecycle.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/py.typed +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/_body.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/auth/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/auth/abc.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/auth/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/auth/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/auth/middleware.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/autocrud.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/checks.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/cors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/_auto_ai.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/_auto_auth.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/_auto_sql.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/adapter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/auto.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/health.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/fastapi/sql.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/model.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/_jobs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/_refusals.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/checks.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/interfaces.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/manifest.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/triggers/http.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/triggers/schedule.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/triggers/sns.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/serverless/aws/lambda_/triggers/sqs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_operators.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/bytewax/runner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/compiler/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/compiler/_bindings.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/compiler/_compiler.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/compiler/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/compiler/_plan.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/core/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/core/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/core/_exceptions.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/core/_message.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/core/_tracing.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/core/_typing.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/graph/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/graph/_flow.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/_codec.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/_config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/_errors.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/_message.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/_record.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/_wire.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/mongo/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/mongo/_config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/mongo/_event.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/mongo/_normalize.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_boundary.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_branches.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_decompose.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_fork.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_helpers.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_mongo.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_protocols.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_router.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_shape.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_sink.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_step.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_table/_clickhouse.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_table/_delta.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_table/_sqlalchemy.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_table/common.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_table/config.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/_with.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/nodes/refs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/streaming/testing.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/agents.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/gateway.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/jobs.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/lambda_http.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/runner.py +0 -0
- {loom_kernel-10.2.0 → loom_kernel-10.3.0}/src/loom/testing/serverless.py +0 -0
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
### lambda
|
|
6
6
|
|
|
7
|
+
- **lambda:** `identity` is required on `eventbridge`, `s3`, `sns` and
|
|
8
|
+
`schedule` triggers: a trigger without one fails to load, so no automatic
|
|
9
|
+
change runs without an actor. An `identity.attributes` key under the
|
|
10
|
+
reserved `loom:` prefix fails to load too.
|
|
11
|
+
|
|
7
12
|
- **lambda:** the deploy manifest reuses the loader: `served_routes(source,
|
|
8
13
|
select_interfaces=None)` reads and validates `app.rest.interfaces` and
|
|
9
14
|
`app.rest.disable_routes` itself, the placeholders are read by OmegaConf's
|
|
@@ -49,6 +54,37 @@
|
|
|
49
54
|
|
|
50
55
|
## ✨ Features
|
|
51
56
|
|
|
57
|
+
### audit
|
|
58
|
+
|
|
59
|
+
- **audit:** a model marked `Audited` records every insert, delete and
|
|
60
|
+
value-changing update in its store's `audit_log`: the person
|
|
61
|
+
(`subject`, `mechanism`, `on_behalf_of`), the request (`trace_id`), the
|
|
62
|
+
changed columns, the row's scopes and the connection. Written by a trigger
|
|
63
|
+
of guard revision 3 in the same transaction, append-only for everyone,
|
|
64
|
+
readable only by the `<schema>_auditor` role, partitioned by month.
|
|
65
|
+
Excluded and secret columns are recorded as redacted. Configured under
|
|
66
|
+
`stores.<name>.schema.audit` (`enabled`, `retention_months`, `reader`).
|
|
67
|
+
Run `loom schema bootstrap` from this release before marking a table:
|
|
68
|
+
revision 3 is one-way, and an application with audited tables refuses to
|
|
69
|
+
start on an older guard. See "Audit" in the Postgres RLS guide and ADR 0009.
|
|
70
|
+
- **audit:** every transaction on an external Postgres store sets
|
|
71
|
+
`loom.actor.subject`, `loom.actor.mechanism`, `loom.actor.on_behalf_of`
|
|
72
|
+
and `loom.trace_id`, scoped store or not. A product `SessionSettings` may
|
|
73
|
+
not set any `loom.` key.
|
|
74
|
+
- **audit:** the identity of an event trigger acts on behalf of the caller
|
|
75
|
+
AWS recorded: an S3 record's `userIdentity.principalId`, or the
|
|
76
|
+
`detail.userIdentity.arn` of an EventBridge event from an `aws.` source.
|
|
77
|
+
`loom:on_behalf_of` is reserved: JWT claims under `loom:` are dropped.
|
|
78
|
+
- **cli:** `loom schema bootstrap` (as the superuser, sets the migrator's and
|
|
79
|
+
each login's password from `LOOM_DB_PASSWORD_<USER>`), `loom schema verify`
|
|
80
|
+
(exit 1 on drift, lists expired audit partitions) and
|
|
81
|
+
`loom schema audit drop-expired` (one partition past the retention per run).
|
|
82
|
+
- **audit:** the log's partitions are UTC months kept twelve months ahead by
|
|
83
|
+
every deploy and by `loom schema audit ensure-partitions`, meant for a
|
|
84
|
+
scheduler; `verify` fails and startup warns with fewer than three months left.
|
|
85
|
+
- **check:** `loom check --deploy` warns (`loom.audit.W001`) about a store
|
|
86
|
+
whose audit is disabled.
|
|
87
|
+
|
|
52
88
|
### jobs
|
|
53
89
|
|
|
54
90
|
- **jobs:** `app.job_service` (`inline`, `celery` or `module:Class` built with
|
|
@@ -100,6 +100,7 @@ def _load_check_packages() -> None:
|
|
|
100
100
|
"""Import the packages registering loom's checks; the REST ones need the rest extra."""
|
|
101
101
|
importlib.import_module("loom.core.logger")
|
|
102
102
|
importlib.import_module("loom.core.repository.abc")
|
|
103
|
+
importlib.import_module("loom.core.persistence.audit_checks")
|
|
103
104
|
if importlib.util.find_spec("fastapi") is not None:
|
|
104
105
|
importlib.import_module("loom.rest")
|
|
105
106
|
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""``loom schema``: the commands that prepare a row-scoped schema."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from collections.abc import Awaitable, Callable
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import TYPE_CHECKING, Annotated, Any, NoReturn, TypeVar
|
|
9
|
+
|
|
10
|
+
import typer
|
|
11
|
+
import yaml
|
|
12
|
+
|
|
13
|
+
from loom.core.config.errors import ConfigError
|
|
14
|
+
from loom.core.config.keys import ConfigKey
|
|
15
|
+
from loom.core.environment import (
|
|
16
|
+
DB_PASSWORD_PREFIX,
|
|
17
|
+
MIGRATOR_URL_VARIABLE,
|
|
18
|
+
SUPERUSER_URL_VARIABLE,
|
|
19
|
+
VERIFY_URL_VARIABLE,
|
|
20
|
+
loom_variable,
|
|
21
|
+
)
|
|
22
|
+
from loom.core.locator import load_application
|
|
23
|
+
from loom.core.persistence.stores import BACKEND_KEY, DEFAULT_STORE, SQLALCHEMY_BACKEND
|
|
24
|
+
from loom.core.schema_names import SchemaNames
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from sqlalchemy.ext.asyncio import AsyncConnection
|
|
28
|
+
|
|
29
|
+
from loom.core.repository.sqlalchemy.rls import BootstrapConfig
|
|
30
|
+
from loom.core.repository.sqlalchemy.rls.verify import Report
|
|
31
|
+
|
|
32
|
+
# The commands below import SQLAlchemy inside their bodies: the CLI loads
|
|
33
|
+
# without it, and only these commands require it.
|
|
34
|
+
|
|
35
|
+
_T = TypeVar("_T")
|
|
36
|
+
_STORES = str(ConfigKey.STORES) # a plain str: yaml.safe_dump refuses a StrEnum key
|
|
37
|
+
_STORE_PATH = f"{_STORES}.{DEFAULT_STORE}"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
schema_app = typer.Typer(no_args_is_help=True, help="Prepare a row-scoped schema.")
|
|
41
|
+
audit_app = typer.Typer(no_args_is_help=True, help="Operate the store's audit log.")
|
|
42
|
+
schema_app.add_typer(audit_app, name="audit")
|
|
43
|
+
|
|
44
|
+
_CONFIG_OPTION = typer.Option("--config", help="A config directory or file, as the app loads it.")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@schema_app.command("init")
|
|
48
|
+
def init(
|
|
49
|
+
name: Annotated[str, typer.Argument(help="The application schema.")],
|
|
50
|
+
config: Annotated[
|
|
51
|
+
Path | None,
|
|
52
|
+
typer.Option("--config", help="Merge the names into this configuration file."),
|
|
53
|
+
] = None,
|
|
54
|
+
) -> None:
|
|
55
|
+
"""Derive the names around a schema once and write them into the configuration.
|
|
56
|
+
|
|
57
|
+
Without ``--config`` the block is printed. With it the names are merged
|
|
58
|
+
into ``stores.default.schema``, declaring the store with ``backend:
|
|
59
|
+
sqlalchemy`` when the file does not; a name the product already changed
|
|
60
|
+
is never overwritten.
|
|
61
|
+
"""
|
|
62
|
+
try:
|
|
63
|
+
block = _block(name, SchemaNames.derived(name))
|
|
64
|
+
if config is None:
|
|
65
|
+
document = {
|
|
66
|
+
_STORES: {DEFAULT_STORE: {BACKEND_KEY: SQLALCHEMY_BACKEND, "schema": block}}
|
|
67
|
+
}
|
|
68
|
+
typer.echo(yaml.safe_dump(document, sort_keys=False), nl=False)
|
|
69
|
+
return
|
|
70
|
+
_write(config, block)
|
|
71
|
+
except (ValueError, yaml.YAMLError) as exc:
|
|
72
|
+
typer.echo(str(exc), err=True)
|
|
73
|
+
raise typer.Exit(1) from exc
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _write(config: Path, block: dict[str, Any]) -> None:
|
|
77
|
+
document = _load(config)
|
|
78
|
+
store = _section(_section(document, _STORES, _STORES), DEFAULT_STORE, _STORE_PATH)
|
|
79
|
+
backend = store.setdefault(BACKEND_KEY, SQLALCHEMY_BACKEND)
|
|
80
|
+
if backend != SQLALCHEMY_BACKEND:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"{_STORE_PATH}.{BACKEND_KEY} is {backend!r}; "
|
|
83
|
+
f"a row-scoped schema needs {SQLALCHEMY_BACKEND}"
|
|
84
|
+
)
|
|
85
|
+
schema = _section(store, "schema", f"{_STORE_PATH}.schema")
|
|
86
|
+
conflicts = _merge(schema, block, f"{_STORE_PATH}.schema")
|
|
87
|
+
if conflicts:
|
|
88
|
+
raise ValueError(
|
|
89
|
+
"these names differ from the derived ones and were kept: " + ", ".join(conflicts)
|
|
90
|
+
)
|
|
91
|
+
config.write_text(yaml.safe_dump(document, sort_keys=False))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _load(config: Path) -> dict[str, Any]:
|
|
95
|
+
if not config.exists():
|
|
96
|
+
return {}
|
|
97
|
+
loaded = yaml.safe_load(config.read_text())
|
|
98
|
+
if loaded is None:
|
|
99
|
+
return {}
|
|
100
|
+
if not isinstance(loaded, dict):
|
|
101
|
+
raise ValueError(f"{config} must hold a mapping at its top level")
|
|
102
|
+
return loaded
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _section(parent: dict[str, Any], key: str, path: str) -> dict[str, Any]:
|
|
106
|
+
current = parent.get(key)
|
|
107
|
+
if current is None:
|
|
108
|
+
current = parent[key] = {}
|
|
109
|
+
if not isinstance(current, dict):
|
|
110
|
+
raise ValueError(f"{path} must be a mapping")
|
|
111
|
+
return current
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _block(name: str, names: SchemaNames) -> dict[str, Any]:
|
|
115
|
+
return {
|
|
116
|
+
"name": name,
|
|
117
|
+
"guard": names.guard,
|
|
118
|
+
"groups": {"readers": names.readers, "writers": names.writers},
|
|
119
|
+
"version_tables": {"structure": names.version_table, "data": names.data_version_table},
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _merge(target: dict[str, Any], values: dict[str, Any], path: str) -> list[str]:
|
|
124
|
+
conflicts: list[str] = []
|
|
125
|
+
for key, value in values.items():
|
|
126
|
+
current = target.get(key)
|
|
127
|
+
if current is None:
|
|
128
|
+
target[key] = value
|
|
129
|
+
elif isinstance(value, dict) and isinstance(current, dict):
|
|
130
|
+
conflicts += _merge(current, value, f"{path}.{key}")
|
|
131
|
+
elif current != value:
|
|
132
|
+
conflicts.append(f"{path}.{key}")
|
|
133
|
+
return conflicts
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@schema_app.command("bootstrap")
|
|
137
|
+
def bootstrap(config: Annotated[Path, _CONFIG_OPTION]) -> None:
|
|
138
|
+
"""Install or upgrade the guard and configure roles, as the superuser; idempotent.
|
|
139
|
+
|
|
140
|
+
The superuser URL comes from ``LOOM_SUPERUSER_URL`` and the password of the
|
|
141
|
+
migrator and of each database user with a login from ``LOOM_DB_PASSWORD_<USER>``.
|
|
142
|
+
"""
|
|
143
|
+
from loom.core.repository.sqlalchemy.rls import apply_bootstrap
|
|
144
|
+
|
|
145
|
+
try:
|
|
146
|
+
settings = _bootstrap_config(config)
|
|
147
|
+
logins = [settings.roles.migrator] + [
|
|
148
|
+
name for name, user in settings.database_users.items() if user.login
|
|
149
|
+
]
|
|
150
|
+
passwords = {name: _env(DB_PASSWORD_PREFIX + name.upper()) for name in logins}
|
|
151
|
+
asyncio.run(apply_bootstrap(_env(SUPERUSER_URL_VARIABLE), settings, passwords))
|
|
152
|
+
except ConfigError as exc:
|
|
153
|
+
_fail(exc)
|
|
154
|
+
typer.echo(f"guard of {config} is installed and configured")
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@schema_app.command("verify")
|
|
158
|
+
def verify_schema(config: Annotated[Path, _CONFIG_OPTION]) -> None:
|
|
159
|
+
"""Compare the database with the application; exit 1 on any drift.
|
|
160
|
+
|
|
161
|
+
The URL comes from ``LOOM_VERIFY_URL``, else ``LOOM_SUPERUSER_URL``: the
|
|
162
|
+
guard's configuration row needs a privileged reader. Audit partitions past
|
|
163
|
+
the retention are listed, not counted as drift.
|
|
164
|
+
"""
|
|
165
|
+
from loom.core.repository.sqlalchemy.rls import verify
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
application = load_application(str(config))
|
|
169
|
+
url = loom_variable(VERIFY_URL_VARIABLE) or _env(SUPERUSER_URL_VARIABLE)
|
|
170
|
+
report = asyncio.run(verify(url, application))
|
|
171
|
+
except ConfigError as exc:
|
|
172
|
+
_fail(exc)
|
|
173
|
+
_print_report(report)
|
|
174
|
+
if not report.ok:
|
|
175
|
+
raise typer.Exit(1)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _print_report(report: Report) -> None:
|
|
179
|
+
"""One line per finding, then one per audit partition past the retention."""
|
|
180
|
+
for finding in report.findings:
|
|
181
|
+
subject = f"{finding.table} " if finding.table else ""
|
|
182
|
+
typer.echo(f"{subject}{finding.check}: expected {finding.expected}, found {finding.actual}")
|
|
183
|
+
for partition in report.expired_audit_partitions:
|
|
184
|
+
typer.echo(f"expired audit partition: {partition}")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@audit_app.command("drop-expired")
|
|
188
|
+
def drop_expired() -> None:
|
|
189
|
+
"""Drop the oldest audit partition past the retention, as the migrator; one per run."""
|
|
190
|
+
from loom.core.repository.sqlalchemy.rls.audit import drop_expired_audit_partition
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
dropped = asyncio.run(_as_migrator(drop_expired_audit_partition))
|
|
194
|
+
except ConfigError as exc:
|
|
195
|
+
_fail(exc)
|
|
196
|
+
typer.echo(f"dropped {dropped}" if dropped else "no audit partition is past the retention")
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@audit_app.command("ensure-partitions")
|
|
200
|
+
def ensure_partitions() -> None:
|
|
201
|
+
"""Create the audit partitions missing in the next twelve months, as the migrator.
|
|
202
|
+
|
|
203
|
+
Idempotent; meant for a scheduler between deploys (monthly is enough).
|
|
204
|
+
"""
|
|
205
|
+
from loom.core.repository.sqlalchemy.rls.audit import ensure_audit_partitions
|
|
206
|
+
|
|
207
|
+
try:
|
|
208
|
+
created = asyncio.run(_as_migrator(ensure_audit_partitions))
|
|
209
|
+
except ConfigError as exc:
|
|
210
|
+
_fail(exc)
|
|
211
|
+
typer.echo(f"created {created} audit partition(s)")
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
async def _as_migrator(action: Callable[[AsyncConnection], Awaitable[_T]]) -> _T:
|
|
215
|
+
"""Run *action* in one transaction as the migrator (``LOOM_MIGRATOR_URL``)."""
|
|
216
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
|
217
|
+
from sqlalchemy.pool import NullPool
|
|
218
|
+
|
|
219
|
+
engine = create_async_engine(_env(MIGRATOR_URL_VARIABLE), poolclass=NullPool)
|
|
220
|
+
try:
|
|
221
|
+
async with engine.begin() as connection:
|
|
222
|
+
return await action(connection)
|
|
223
|
+
finally:
|
|
224
|
+
await engine.dispose()
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def _bootstrap_config(config: Path) -> BootstrapConfig:
|
|
228
|
+
settings = load_application(str(config)).bootstrap
|
|
229
|
+
if settings is None:
|
|
230
|
+
raise ConfigError(f"{config} declares no row-scoped schema to bootstrap")
|
|
231
|
+
return settings
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def _env(name: str) -> str:
|
|
235
|
+
value = loom_variable(name)
|
|
236
|
+
if not value:
|
|
237
|
+
raise ConfigError(f"set {name}")
|
|
238
|
+
return value
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _fail(exc: Exception) -> NoReturn:
|
|
242
|
+
typer.echo(str(exc), err=True)
|
|
243
|
+
raise typer.Exit(1) from exc
|
|
@@ -47,6 +47,7 @@ from sqlalchemy.sql.schema import DEFAULT_NAMING_CONVENTION
|
|
|
47
47
|
from loom.core.backend.core_model import CoreModel, CoreProfilePlan, CoreRelationStep
|
|
48
48
|
from loom.core.backend.scoped_ddl import SCHEMA_KEY, register_listeners
|
|
49
49
|
from loom.core.config import ConfigError
|
|
50
|
+
from loom.core.model.audited import AuditedTable, AuditedTables, audited_table, is_audited
|
|
50
51
|
from loom.core.model.enums import Cardinality, OnDelete, ServerDefault, ServerOnUpdate
|
|
51
52
|
from loom.core.model.field import ColumnType, Field
|
|
52
53
|
from loom.core.model.introspection import (
|
|
@@ -127,6 +128,7 @@ class _Compilation:
|
|
|
127
128
|
core: dict[type, CoreModel]
|
|
128
129
|
pending: dict[type, dict[str, Relation]]
|
|
129
130
|
scoped: dict[tuple[str | None, str], ScopedTable] = field(default_factory=dict)
|
|
131
|
+
audited: dict[tuple[str | None, str], AuditedTable] = field(default_factory=dict)
|
|
130
132
|
|
|
131
133
|
|
|
132
134
|
_COMPILATION_KEY = "loom.compilation"
|
|
@@ -165,6 +167,11 @@ def scoped_tables(metadata: MetaData | None = None) -> Mapping[tuple[str | None,
|
|
|
165
167
|
return dict(_compilation_for(metadata).scoped)
|
|
166
168
|
|
|
167
169
|
|
|
170
|
+
def audited_tables(metadata: MetaData | None = None) -> AuditedTables:
|
|
171
|
+
"""Audited tables compiled into ``metadata``, keyed by ``(schema, name)``."""
|
|
172
|
+
return dict(_compilation_for(metadata).audited)
|
|
173
|
+
|
|
174
|
+
|
|
168
175
|
def _build_sa_column_type(col_type: ColumnType) -> Any:
|
|
169
176
|
if col_type.type_name == "Postgres.ARRAY":
|
|
170
177
|
if len(col_type.args) != 1:
|
|
@@ -269,7 +276,18 @@ def _compile_model(
|
|
|
269
276
|
comp.compiled[struct_cls] = sa_cls
|
|
270
277
|
comp.tables[table_name] = sa_cls
|
|
271
278
|
comp.pending[struct_cls] = get_relations(struct_cls)
|
|
272
|
-
|
|
279
|
+
_register_protection(struct_cls, sa_cls.__table__, comp, scopes, partition)
|
|
280
|
+
return sa_cls
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def _register_protection(
|
|
284
|
+
struct_cls: type,
|
|
285
|
+
table: Any,
|
|
286
|
+
comp: _Compilation,
|
|
287
|
+
scopes: tuple[Any, ...],
|
|
288
|
+
partition: Any,
|
|
289
|
+
) -> None:
|
|
290
|
+
"""Record what the guard protects on *table*: its scopes and its audit trigger."""
|
|
273
291
|
scoped = None
|
|
274
292
|
if scopes:
|
|
275
293
|
scoped = ScopedTable(
|
|
@@ -280,6 +298,8 @@ def _compile_model(
|
|
|
280
298
|
partition_by=None if partition is None else partition.column,
|
|
281
299
|
)
|
|
282
300
|
comp.scoped[(table.schema, table.name)] = scoped
|
|
301
|
+
if is_audited(struct_cls):
|
|
302
|
+
comp.audited[(table.schema, table.name)] = _audited(struct_cls, table)
|
|
283
303
|
schema = comp.metadata.info.get(SCHEMA_KEY)
|
|
284
304
|
if schema is not None:
|
|
285
305
|
register_listeners(
|
|
@@ -288,7 +308,25 @@ def _compile_model(
|
|
|
288
308
|
scoped=scoped,
|
|
289
309
|
privileges=declared_privileges(struct_cls),
|
|
290
310
|
)
|
|
291
|
-
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def _audited(struct_cls: type, table: Any) -> AuditedTable:
|
|
314
|
+
"""Compile the audit declaration of *struct_cls* onto its *table*.
|
|
315
|
+
|
|
316
|
+
Raises:
|
|
317
|
+
ConfigError: When an excluded column does not exist, or an excluded or
|
|
318
|
+
secret column is part of the primary key.
|
|
319
|
+
"""
|
|
320
|
+
try:
|
|
321
|
+
return audited_table(
|
|
322
|
+
struct_cls,
|
|
323
|
+
schema=table.schema,
|
|
324
|
+
name=table.name,
|
|
325
|
+
columns=(column.name for column in table.columns),
|
|
326
|
+
key_columns=(column.name for column in table.primary_key.columns),
|
|
327
|
+
)
|
|
328
|
+
except ValueError as exc:
|
|
329
|
+
raise ConfigError(str(exc)) from exc
|
|
292
330
|
|
|
293
331
|
|
|
294
332
|
def _refuse_undeclared_column_types(
|
|
@@ -55,6 +55,18 @@ SPARK_IVY_DIR_VARIABLE: Final = "LOOM_SPARK_IVY_DIR"
|
|
|
55
55
|
SPARK_OFFLINE_VARIABLE: Final = "LOOM_SPARK_OFFLINE"
|
|
56
56
|
"""``1`` makes the Spark test session use only cached jars."""
|
|
57
57
|
|
|
58
|
+
SUPERUSER_URL_VARIABLE: Final = "LOOM_SUPERUSER_URL"
|
|
59
|
+
"""Database URL ``loom schema bootstrap`` installs the guard with."""
|
|
60
|
+
|
|
61
|
+
VERIFY_URL_VARIABLE: Final = "LOOM_VERIFY_URL"
|
|
62
|
+
"""Database URL ``loom schema verify`` reads the catalogue with."""
|
|
63
|
+
|
|
64
|
+
MIGRATOR_URL_VARIABLE: Final = "LOOM_MIGRATOR_URL"
|
|
65
|
+
"""Database URL ``loom schema audit drop-expired`` drops a partition with."""
|
|
66
|
+
|
|
67
|
+
DB_PASSWORD_PREFIX: Final = "LOOM_DB_PASSWORD_"
|
|
68
|
+
"""Prefix of the variables holding a database login's password, by upper-case login."""
|
|
69
|
+
|
|
58
70
|
_BASE_CONFIG_FILE: Final = "base.yaml"
|
|
59
71
|
|
|
60
72
|
|
|
@@ -289,13 +301,17 @@ def select_config_paths(
|
|
|
289
301
|
|
|
290
302
|
__all__ = [
|
|
291
303
|
"CONFIG_VARIABLE",
|
|
304
|
+
"DB_PASSWORD_PREFIX",
|
|
292
305
|
"ENVIRONMENT_VARIABLE",
|
|
293
306
|
"ETL_CONFIG_VARIABLE",
|
|
307
|
+
"MIGRATOR_URL_VARIABLE",
|
|
294
308
|
"OVERRIDE_PREFIX",
|
|
295
309
|
"SPARK_IVY_DIR_VARIABLE",
|
|
296
310
|
"SPARK_OFFLINE_VARIABLE",
|
|
297
311
|
"SPOOL_DIR_VARIABLE",
|
|
298
312
|
"STORAGE_CONFIG_VARIABLE",
|
|
313
|
+
"SUPERUSER_URL_VARIABLE",
|
|
314
|
+
"VERIFY_URL_VARIABLE",
|
|
299
315
|
"Environment",
|
|
300
316
|
"config_source_paths",
|
|
301
317
|
"configured_variable",
|
|
@@ -7,11 +7,18 @@ no transport and no infrastructure.
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from loom.core.identity.context import current_identity, reset_identity, set_identity
|
|
10
|
-
from loom.core.identity.identity import
|
|
10
|
+
from loom.core.identity.identity import (
|
|
11
|
+
ANONYMOUS,
|
|
12
|
+
ON_BEHALF_OF_ATTRIBUTE,
|
|
13
|
+
RESERVED_ATTRIBUTE_PREFIX,
|
|
14
|
+
Identity,
|
|
15
|
+
)
|
|
11
16
|
from loom.core.identity.issuer import IssuedToken, TokenIssuer
|
|
12
17
|
|
|
13
18
|
__all__ = [
|
|
14
19
|
"ANONYMOUS",
|
|
20
|
+
"ON_BEHALF_OF_ATTRIBUTE",
|
|
21
|
+
"RESERVED_ATTRIBUTE_PREFIX",
|
|
15
22
|
"Identity",
|
|
16
23
|
"IssuedToken",
|
|
17
24
|
"TokenIssuer",
|
|
@@ -15,6 +15,10 @@ from types import MappingProxyType
|
|
|
15
15
|
from loom.core.errors import Forbidden, Unauthenticated
|
|
16
16
|
|
|
17
17
|
_EMPTY_ATTRIBUTES: Mapping[str, str] = MappingProxyType({})
|
|
18
|
+
RESERVED_ATTRIBUTE_PREFIX = "loom:"
|
|
19
|
+
"""Attributes under this prefix are set only by loom itself, never by an authenticator."""
|
|
20
|
+
ON_BEHALF_OF_ATTRIBUTE = f"{RESERVED_ATTRIBUTE_PREFIX}on_behalf_of"
|
|
21
|
+
"""The person a system identity acts for; set by loom's event dispatchers and audited."""
|
|
18
22
|
|
|
19
23
|
_NO_SUBJECT_MESSAGE = "Authentication required: the request carries no verified identity."
|
|
20
24
|
|
|
@@ -14,8 +14,8 @@ from __future__ import annotations
|
|
|
14
14
|
import os
|
|
15
15
|
import re
|
|
16
16
|
import sys
|
|
17
|
-
from collections.abc import Mapping
|
|
18
|
-
from dataclasses import dataclass
|
|
17
|
+
from collections.abc import Mapping, Sequence
|
|
18
|
+
from dataclasses import dataclass, field
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
from typing import TYPE_CHECKING, Any, Final, get_args
|
|
21
21
|
|
|
@@ -31,6 +31,7 @@ from loom.core.environment import (
|
|
|
31
31
|
resolve_environment,
|
|
32
32
|
)
|
|
33
33
|
from loom.core.logger import get_logger
|
|
34
|
+
from loom.core.model.audited import AuditedTables
|
|
34
35
|
from loom.core.model.scoped import ScopedTables, declared_scopes
|
|
35
36
|
from loom.core.persistence.database import (
|
|
36
37
|
DatabaseConfig,
|
|
@@ -83,6 +84,17 @@ class Application:
|
|
|
83
84
|
scoped: ScopedTables
|
|
84
85
|
scope_sources: Mapping[str, str]
|
|
85
86
|
store: StoreKey = DEFAULT_STORE
|
|
87
|
+
audited: AuditedTables = field(default_factory=dict)
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def guarded(self) -> bool:
|
|
91
|
+
"""Whether the store needs the guard: it declares scoped or audited tables."""
|
|
92
|
+
return bool(self.scoped or self.audited)
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def active_audited(self) -> AuditedTables:
|
|
96
|
+
"""The audited tables that record rows: the marked ones while ``schema.audit.enabled``."""
|
|
97
|
+
return self.audited if self.database.schema.audit.enabled else {}
|
|
86
98
|
|
|
87
99
|
@property
|
|
88
100
|
def path(self) -> str:
|
|
@@ -119,14 +131,7 @@ def load_application(
|
|
|
119
131
|
ConfigError: When the path is missing, a required key is absent or a
|
|
120
132
|
value has the wrong shape; the message names the key.
|
|
121
133
|
"""
|
|
122
|
-
from sqlalchemy import
|
|
123
|
-
|
|
124
|
-
from loom.core.backend.scoped_ddl import SCHEMA_KEY
|
|
125
|
-
from loom.core.backend.sqlalchemy import (
|
|
126
|
-
compile_all,
|
|
127
|
-
configured_naming_convention,
|
|
128
|
-
scoped_tables,
|
|
129
|
-
)
|
|
134
|
+
from loom.core.backend.sqlalchemy import audited_tables, scoped_tables
|
|
130
135
|
|
|
131
136
|
path = _resolve_path(config_path)
|
|
132
137
|
environment = resolve_environment()
|
|
@@ -143,14 +148,10 @@ def load_application(
|
|
|
143
148
|
if skipped:
|
|
144
149
|
_log.info("StoresNotLoaded", store=store, skipped=skipped)
|
|
145
150
|
schema = database.schema
|
|
146
|
-
metadata =
|
|
147
|
-
naming_convention=configured_naming_convention(schema.naming_convention, path=spec.path)
|
|
148
|
-
)
|
|
149
|
-
if schema.name is not None:
|
|
150
|
-
metadata.info[SCHEMA_KEY] = _schema_name(schema.name, spec.path)
|
|
151
|
-
compile_all(*models, metadata=metadata)
|
|
151
|
+
metadata = _compiled_metadata(models, schema, spec.path)
|
|
152
152
|
scoped = scoped_tables(metadata)
|
|
153
|
-
|
|
153
|
+
audited = audited_tables(metadata)
|
|
154
|
+
bootstrap = _bootstrap(schema, spec.path) if scoped or audited else None
|
|
154
155
|
scope_sources = _scope_sources(schema, scoped, spec.path) if scoped else {}
|
|
155
156
|
return Application(
|
|
156
157
|
models=tuple(models),
|
|
@@ -160,9 +161,26 @@ def load_application(
|
|
|
160
161
|
scoped=scoped,
|
|
161
162
|
scope_sources=scope_sources,
|
|
162
163
|
store=store,
|
|
164
|
+
audited=audited,
|
|
163
165
|
)
|
|
164
166
|
|
|
165
167
|
|
|
168
|
+
def _compiled_metadata(models: Sequence[type], schema: SchemaConfig, path: str) -> MetaData:
|
|
169
|
+
"""A metadata holding *models* compiled under the store's naming convention and schema."""
|
|
170
|
+
from sqlalchemy import MetaData
|
|
171
|
+
|
|
172
|
+
from loom.core.backend.scoped_ddl import SCHEMA_KEY
|
|
173
|
+
from loom.core.backend.sqlalchemy import compile_all, configured_naming_convention
|
|
174
|
+
|
|
175
|
+
metadata = MetaData(
|
|
176
|
+
naming_convention=configured_naming_convention(schema.naming_convention, path=path)
|
|
177
|
+
)
|
|
178
|
+
if schema.name is not None:
|
|
179
|
+
metadata.info[SCHEMA_KEY] = _schema_name(schema.name, path)
|
|
180
|
+
compile_all(*models, metadata=metadata)
|
|
181
|
+
return metadata
|
|
182
|
+
|
|
183
|
+
|
|
166
184
|
def add_code_path(code_path: str | os.PathLike[str], config_dir: Path) -> Path:
|
|
167
185
|
"""Put an application's code directory first on ``sys.path``, once.
|
|
168
186
|
|
|
@@ -228,6 +246,8 @@ def _bootstrap(schema: SchemaConfig, path: str) -> BootstrapConfig:
|
|
|
228
246
|
version_table=version_tables.structure,
|
|
229
247
|
data_version_table=version_tables.data,
|
|
230
248
|
),
|
|
249
|
+
auditor=schema.audit.reader,
|
|
250
|
+
audit_retention_months=schema.audit.retention_months,
|
|
231
251
|
)
|
|
232
252
|
try:
|
|
233
253
|
return config.validated()
|
|
@@ -6,6 +6,7 @@ from loom.core.model._loom_type import (
|
|
|
6
6
|
msgspec_type,
|
|
7
7
|
pydantic_type,
|
|
8
8
|
)
|
|
9
|
+
from loom.core.model.audited import Audited, AuditedTable
|
|
9
10
|
from loom.core.model.base import BaseModel, LoomStructMeta
|
|
10
11
|
from loom.core.model.enums import Cardinality, OnDelete, OnUpdate, ServerDefault, ServerOnUpdate
|
|
11
12
|
from loom.core.model.field import ColumnField, ColumnType, Field, ScopedField
|
|
@@ -56,6 +57,8 @@ from loom.core.model.types import (
|
|
|
56
57
|
from loom.core.model.types_postgres import Postgres
|
|
57
58
|
|
|
58
59
|
__all__ = [
|
|
60
|
+
"Audited",
|
|
61
|
+
"AuditedTable",
|
|
59
62
|
"BaseModel",
|
|
60
63
|
"READ_WRITE",
|
|
61
64
|
"Privilege",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Marker and descriptor for tables whose every row change is recorded in the audit log."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable, Mapping
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import ClassVar
|
|
8
|
+
|
|
9
|
+
from loom.core.model.redaction import is_secret_name
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Audited:
|
|
13
|
+
"""Mark a model as audited; adds no column.
|
|
14
|
+
|
|
15
|
+
Every insert, delete and value-changing update of the table is recorded
|
|
16
|
+
in the store's audit log by a trigger the guard installs. Columns named
|
|
17
|
+
in ``__audit_exclude__``, and every column whose name is a credential
|
|
18
|
+
(:func:`~loom.core.model.redaction.is_secret_name`), are never written
|
|
19
|
+
to the log: a change to one is recorded as redacted. The table needs a
|
|
20
|
+
primary key, and no excluded or secret column may be part of it.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
__audited__: ClassVar[bool] = True
|
|
24
|
+
__audit_exclude__: ClassVar[frozenset[str]] = frozenset()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True, slots=True)
|
|
28
|
+
class AuditedTable:
|
|
29
|
+
"""A compiled audited table: its key columns and the columns never written to the log."""
|
|
30
|
+
|
|
31
|
+
schema: str | None
|
|
32
|
+
name: str
|
|
33
|
+
key_columns: tuple[str, ...]
|
|
34
|
+
excluded: frozenset[str]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
AuditedTables = Mapping[tuple[str | None, str], AuditedTable] # by schema and name
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def is_audited(model: type) -> bool:
|
|
41
|
+
"""Whether *model* carries the :class:`Audited` marker."""
|
|
42
|
+
return bool(getattr(model, "__audited__", False))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def audited_table(
|
|
46
|
+
model: type,
|
|
47
|
+
*,
|
|
48
|
+
schema: str | None,
|
|
49
|
+
name: str,
|
|
50
|
+
columns: Iterable[str],
|
|
51
|
+
key_columns: Iterable[str],
|
|
52
|
+
) -> AuditedTable:
|
|
53
|
+
"""Compile *model*'s audit declaration.
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
ValueError: When the table has no primary key, an excluded column does
|
|
57
|
+
not exist, or an excluded or secret column is part of the primary
|
|
58
|
+
key; the message names the table and the column.
|
|
59
|
+
"""
|
|
60
|
+
names = tuple(columns)
|
|
61
|
+
keys = tuple(key_columns)
|
|
62
|
+
if not keys:
|
|
63
|
+
raise ValueError(f"audited table {name} has no primary key; the log keys each row by it")
|
|
64
|
+
declared = frozenset(getattr(model, "__audit_exclude__", frozenset()))
|
|
65
|
+
unknown = sorted(declared - set(names))
|
|
66
|
+
if unknown:
|
|
67
|
+
raise ValueError(f"audited table {name} excludes unknown columns {unknown}")
|
|
68
|
+
excluded = declared | {column for column in names if is_secret_name(column)}
|
|
69
|
+
in_key = sorted(excluded & set(keys))
|
|
70
|
+
if in_key:
|
|
71
|
+
raise ValueError(
|
|
72
|
+
f"audited table {name}: {in_key} cannot be excluded from the log "
|
|
73
|
+
"and be part of the primary key"
|
|
74
|
+
)
|
|
75
|
+
return AuditedTable(schema=schema, name=name, key_columns=keys, excluded=excluded)
|