matrx-orm 3.1.256__tar.gz → 3.1.258__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.
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/PKG-INFO +1 -1
- matrx_orm-3.1.258/docs/attachment-concurrency.md +28 -0
- matrx_orm-3.1.258/docs/index.md +10 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/FEATURE.md +38 -110
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/resilience.py +46 -6
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/transaction.py +1 -1
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/write_retry.py +1 -1
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/FEATURE.md +57 -123
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/backup_restore.py +121 -94
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/mutation_receipts.py +57 -2
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/native_enable.py +9 -5
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/pyproject.toml +1 -1
- matrx_orm-3.1.258/tests/level1/test_mutation_receipt_locator.py +143 -0
- matrx_orm-3.1.258/tests/level1/test_resilience_policy.py +255 -0
- matrx_orm-3.1.258/tests/test_backup_restore_ordering.py +370 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_native_enable.py +45 -11
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/.gitignore +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/AGENTS.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/BASE_CLASS_METHODS.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/CHANGELOG.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/CLAUDE.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/MODEL_API.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/database/orm/extended/managers/ai_model_base.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/docs/migrations.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/FEATURE.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/adapters/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/adapters/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/adapters/async_postgresql.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/adapters/base_adapter.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/adapters/postgrest_client_adapter.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/adapters/supabase_adapter.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/admin/FEATURE.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/admin/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/admin/router.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/api/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/api/auth.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/api/config.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/api/handlers.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/api/protocol.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/api/server.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/associations.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/cache_debug.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/catalog.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/catalog_sql.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/client/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/client/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/client/postgres_connection.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/client/postgrest.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/client/supabase_auth.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/client/supabase_config.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/client/supabase_manager.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/EXTENDED-TASK.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/RELATIONS-TASKS.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/TASKS.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/admin_lane.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/async_db_manager.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/base.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/config.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/connections.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/db_function.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/diagnostics.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/expressions.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/extended.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/fields.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/foreign_session_state.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/introspection.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/listen.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/loop_filters.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/model_dto.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/model_view.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/one_database.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/paginator.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/pool_maintenance.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/pool_watch.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/pooler_role.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/pydantic_bridge.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/read_write.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/registry.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/relations.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/rls_session.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/session_context.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/signals.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/statement_ceiling.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/tls.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/types.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/core/write_queue.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/entity.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/error_handling.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/exceptions.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/extended/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/extended/app_error_handler.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/identity_rule.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/local_sqlite.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/middleware/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/middleware/base.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/cli.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/ddl.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/diff.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/executor.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/integration.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/loader.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/operations.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/state.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/migrations/table_filter.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/no_org_assignment.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/FEATURE.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/bulk_update_values.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/catalog_select.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/conflict.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/conflict_writes.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/create.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/db_functions.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/delete.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/dynamic_admin.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/dynamic_crud.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/graph_walk.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/latest_rows.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/queue_claim.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/read.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/relational_backfill.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/staging_load.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/operations/update.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/platform_access.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/platform_db.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/py.typed +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/pytest_lock_guard.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/pytest_plugin.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/python_sql/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/python_sql/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/python_sql/db_objects.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/python_sql/table_detailed_relationships.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/python_sql/table_typescript_relationship.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/query/FEATURE.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/query/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/query/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/query/builder.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/query/executor.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/resources/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/resources/additional-assigners-2026-09-12.json +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/resources/org_assignment_trigger_baseline.json +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/FEATURE.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/code_handler.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/codegen_writer.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/columns.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/common.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/diff_preview.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/entity_capabilities.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/excluded_targets.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/generator.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/helpers/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/helpers/base_generators.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/helpers/entity_generators.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/helpers/git_checker.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/package_wiring.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/relationships.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/runner.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/schema.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/schema_manager.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/tables.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/schema_builder/views.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/attachments.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/crypto.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/host_authorization.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/items.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/model.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/native_lifecycle.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/native_passkeys.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/native_source.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/org_service.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/org_vault_gate.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/service.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/use_stamp.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/secrets_battery/vault_history.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/coalesce.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/dag.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/errors.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/fallback.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/flush.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/lifecycle.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/managed.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/op.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/reads.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/session.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/session/telemetry.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/sql_executor/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/sql_executor/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/sql_executor/executor.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/sql_executor/queries.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/sql_executor/registry.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/sql_executor/types.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/sql_executor/utils.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/state.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/utils/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/utils/sql_utils.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/utils/type_converters.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/matrx_orm/write_actor.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/scripts/git-branches.sh +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/scripts/publish.sh +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/scripts/release.sh +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/scripts/verify_wheel.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/conftest.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_adapter_registry.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_admin_db_columns.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_admin_response_rendering.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_admin_search_negation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_admin_search_sentinels.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_advisory_lock.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_agent_message.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_api_auth.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_api_config.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_api_handlers.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_api_protocol.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_array_agg_order_by.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_association_trigger_actor_naming.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_associations.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_associations_wiring.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_borrowed_role_never_reaches_server_calls.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_bulk_hydration_offload.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_bulk_update_by_pk.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_bulk_upsert_increment_set_fields.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_cache_debug.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_call_function.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_case_when.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_catalog.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_column_scoped_writes.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_committed_row_guard.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_composite_pk_filter.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_composite_pk_write_paths.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_config.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_conflict_target.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_conflict_writes.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_connection_codecs.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_connection_poison_guard.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_connection_primitives.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_count_composite_distinct.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_count_limit_param_leak.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_db_function_field.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_ddl_generator.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_deadlock_retry.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_derived_table.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_dirty_tracking.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_dynamic_crud.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_exceptions.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_execute_query_integrity_mapping.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_expression_primitives.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_fetch_on_init_holds_whole_table.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_fields.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_filter_jsonb_agg_array_index.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_fk_cycle_resolution.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_from_alias.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_fts.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_func_expression_args.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_graph_walk.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_guarded_read_never_reruns_empty.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_having_annotate_alias.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_insert_ignore_and_admin_primitives.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_introspect_rls_policies.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_join_and_aggregate.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_latest_rows.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_listen_notify.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_local_sqlite.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_lock_contention_retry.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_managed_write_guard.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_matrx_entity.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_migration_diff_types.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_migration_loader.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_model_instance.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_model_meta.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_optimistic_concurrency.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_order_by_expression.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_org_assignment_inventory.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_orm_banners_are_client_safe.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_parameter_name_hydration.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_patch_jsonb_path.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_percentile_cont.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_persisted_count.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_person_scoped_session_bypasses_shared_cache.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_pool_create_never_wedges.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_pool_holder_census.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_pool_loop_recreation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_pool_maintenance.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_postgrest_filters.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_pydantic_bridge.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_query_builder.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_query_error_detail.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_query_executor_sql.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_query_timeout.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_querybuilder_clone_semantics.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_queue_claim.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_read_connection_retry.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_read_write_declared.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_registry.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_registry_multi_database.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_registry_multi_schema.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_registry_reads_outside_the_person_session.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_relational_backfill.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_relations.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_resilience.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_rls_session_scope.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_row_lock_modes.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_schema_exists.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_session_advisory_lock.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_standalone_write_session_context.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_state_cache.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_subquery_filter_raw.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_subquery_in_filter.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_subquery_nested_expressions.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_supabase_auth.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_supabase_config.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_sync_pool_declares_read_write.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_tls.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_transaction_database_identity.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_transaction_gucs_one_round_trip.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_transaction_isolation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_transaction_pool_release_sends_nothing.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_transaction_top_level_cleanup.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_typed_join_projection.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_typed_predicates.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_update_case_expression.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_update_subquery.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_update_with_rebase.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_upsert_default_leak.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_upsert_with_conflict.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_values_jsonb_decode.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_watched_lifecycle.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_wheel_contents.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_write_queue_deadline.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level1/test_write_retry_semantics.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/MODULE_README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/conftest.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_bulk_ops.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_cache_integration.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_crud.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_foreign_keys.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_m2m.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_manager.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_migrations_live.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_query_execution.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/test_schema_diff.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/level2/verify_committed_row_guard_pg17.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/live_pooler_role.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/native_source_cases.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/native_source_oracle.rs +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project/.env.example +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project/README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project/generate.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project/generated/.gitkeep +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project/matrx_orm.yaml +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project/test_schema_generation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project_desktop/.env.example +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project_desktop/README.md +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project_desktop/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project_desktop/client_example.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project_desktop/client_example.ts +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project_desktop/client_supabase_example.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/sample_project_desktop/server.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/entity_tests.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_base_generation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_composite_pk_fk_generation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_composite_unique_generation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_dto_identity_generation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_entity_capability_generation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_enum_ordering.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_excluded_fk_targets.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_generate_schema.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_junction_analysis.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_multi_schema_output.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_schema_analysis.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_sql_expression_defaults.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_table_relationships_query.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema/test_view_generation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema_builder/test_array_default_parsing.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema_builder/test_enum_array_column.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema_builder/test_focused_generation_plan.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema_builder/test_host_models_aggregator.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/schema_builder/test_never_filter_columns.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/__init__.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/conftest.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_a_failed_capture_still_names_the_failure.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_a_grouped_update_writes_only_each_rows_own_fields.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_cache_no_downgrade.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_capture_poison_proof.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_coalesce.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_dag.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_disk_spill_fallback.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_flush_individual_fallback.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_governed_write.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_managed.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_op_enqueue_site.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_pending_insert_honors_operator_filters.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_reads.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_record_error_bounded_insert.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_record_error_group_open.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_record_error_storm.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_session.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_spill_guard_plugin.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/session/test_tests_never_write_live_system_error.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_a_backend_handed_over_mid_transaction_never_takes_our_writes.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_a_bulk_cache_never_stalls_the_loop.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_a_failed_use_stamp_never_fails_the_read.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_a_keyword_column_refuses_generation.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_a_list_of_uuids_binds_as_uuid_array.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_a_read_only_backend_never_refuses_our_writes.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_a_sealed_field_shows_no_character_of_its_value.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_array_arg_element_type.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_attachment_mutation_serialization.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_backup_alias_conflict.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_backup_history_restore.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_backup_restore_live.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_call_function_as.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_call_function_none_mode.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_composite_fk_is_not_a_column_fk.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_database_name_alias.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_db_functions.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_dsn_password_masking.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_dynamic_select_unregistered.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_first_asks_the_database_for_one_row.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_foreign_session_state.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_immutable_insert_or_exact_verify.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_instance_update_runs_expressions.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_jsonb_postgres_illegal_text.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_keyed_digest.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_model_cls_refactor.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_native_lifecycle.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_native_lifecycle_fences.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_native_passkey_receipts.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_native_source.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_no_blocking_asyncpg_tls.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_one_database.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_order_by_desc_nulls_last.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_org_vault_gate.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_package_wiring_views.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_platform_access_strict.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_pooler_role_guard.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_secret_audit_names_its_organization.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_secrets_battery.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_secrets_minting_keys.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_shared_lock_guard.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_sql_param_casts.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_state_cache_sweeps_stale.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_statement_ceiling_warning.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_sync_twins_guard.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_update_result_truthiness.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_user_visible_lookup.py +0 -0
- {matrx_orm-3.1.256 → matrx_orm-3.1.258}/tests/test_vault_aggregate_recovery_stateful.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: matrx-orm
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.258
|
|
4
4
|
Summary: Async-first PostgreSQL ORM with bidirectional migrations, schema introspection, many-to-many relationships, and built-in state caching
|
|
5
5
|
Project-URL: Homepage, https://github.com/AI-Matrix-Engine/aidream-current
|
|
6
6
|
Project-URL: Repository, https://github.com/AI-Matrix-Engine/aidream-current
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Reference
|
|
3
|
+
title: Credential attachment concurrency verification
|
|
4
|
+
description: Real-router race probe for parent-held attachment mutation and byte materialization.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Credential attachment concurrency verification
|
|
8
|
+
|
|
9
|
+
Use the real Vault router and auth provider as `admin@admin.com`, with an
|
|
10
|
+
isolated agent-owned session and a new item stamped with this run's `test_run_id`.
|
|
11
|
+
Never reuse another run's item or touch the owner's credentials.
|
|
12
|
+
|
|
13
|
+
1. Pause an attachment request after it takes the parent lock but before its
|
|
14
|
+
child write. Release it first: it must return 201. The following item delete
|
|
15
|
+
must return 204, and a fresh router list must have no live child.
|
|
16
|
+
2. Reverse the schedule: pause the attachment request before parent-lock
|
|
17
|
+
acquisition, complete the item delete, then release the request. It must
|
|
18
|
+
refuse and leave no live child.
|
|
19
|
+
3. Repeat both schedules with download and trusted resolve paused before byte
|
|
20
|
+
materialization. No child bytes may escape after the winning deletion.
|
|
21
|
+
4. Remove each run-owned disposable item through the canonical cascade, archive
|
|
22
|
+
retained run-owned fixtures and independently verify no live test records
|
|
23
|
+
remain. End and verify rejection of the owned session; close only this run's
|
|
24
|
+
browser/process resources and clear any owned clipboard content.
|
|
25
|
+
|
|
26
|
+
This probe complements the focused serialization guards; offline source tests do
|
|
27
|
+
not establish live concurrency acceptance. Pending product acceptance belongs in
|
|
28
|
+
the [Vault register](../../../common-docs/projects/credential-sharing-browser-login/REGISTER.md).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Reference
|
|
3
|
+
title: matrx-orm verification and migration guides
|
|
4
|
+
description: Focused package operating guides.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Package guides
|
|
8
|
+
|
|
9
|
+
- [Migrations](migrations.md)
|
|
10
|
+
- [Credential attachment concurrency verification](attachment-concurrency.md)
|
|
@@ -32,7 +32,9 @@ generated model therefore remains reachable through
|
|
|
32
32
|
`get_model_by_table_name(schema, table)` even when its class does not repeat the
|
|
33
33
|
resolved table name as a raw attribute.
|
|
34
34
|
|
|
35
|
-
Pinned by `tests/level1/test_registry.py`.
|
|
35
|
+
Pinned by `tests/level1/test_registry.py`. Registry, catalog, recovery and diagnostic
|
|
36
|
+
identities use exact `schema.table`; bare names are uncached discovery terms and
|
|
37
|
+
ambiguous lookups refuse rather than choosing a schema.
|
|
36
38
|
|
|
37
39
|
## Database execution errors
|
|
38
40
|
|
|
@@ -46,9 +48,7 @@ rejects the statement before execution, so this narrow failure is replay-safe;
|
|
|
46
48
|
ambiguous write failures remain single-attempt.
|
|
47
49
|
|
|
48
50
|
**A write may set its own statement ceiling — `Model.create(statement_timeout=…)`
|
|
49
|
-
(seconds, keyword-only).**
|
|
50
|
-
while; the write door had nothing, so the pool's `command_timeout` (10s) was the
|
|
51
|
-
only ceiling any INSERT could have. It threads
|
|
51
|
+
(seconds, keyword-only).** It threads
|
|
52
52
|
`Model.create` → `operations/create` → `query["statement_timeout"]` →
|
|
53
53
|
`QueryExecutor.insert` → `adapter.execute_write(statement_timeout=)` →
|
|
54
54
|
`execute_query(statement_timeout=)` → asyncpg `fetch(..., timeout=)`, so it
|
|
@@ -56,8 +56,7 @@ overrides — never widens — anything else: pool-acquire timeout and every oth
|
|
|
56
56
|
statement are untouched. It raises no retry rights: an ambiguous write is still
|
|
57
57
|
single-attempt HERE, and a caller that re-issues one must own an idempotency key
|
|
58
58
|
(matrx-graph's checkpoint INSERT is keyed by checkpoint id and reads the row back).
|
|
59
|
-
|
|
60
|
-
load and killed a paid-for workflow run. Guard:
|
|
59
|
+
Guard:
|
|
61
60
|
`tests/level1/test_query_timeout.py::TestInsertStatementTimeout`.
|
|
62
61
|
|
|
63
62
|
**A statement the SERVER canceled to break a lock collision is re-issued — the
|
|
@@ -71,19 +70,15 @@ unretryable. Class-40 siblings stay out by name — `40003`
|
|
|
71
70
|
this completed", and `40002` is a constraint failure wearing a class-40 code.
|
|
72
71
|
The victim is often innocent of any write: a multi-table READ is canceled
|
|
73
72
|
whenever a concurrent DDL session wants AccessExclusiveLock on a table it already
|
|
74
|
-
holds a lock on
|
|
75
|
-
on /chat.
|
|
73
|
+
holds a lock on.
|
|
76
74
|
|
|
77
75
|
🚨 **THERE IS ONE LOOP AND ONE BUDGET.** `matrx_orm/core/write_retry.py` owns the
|
|
78
76
|
classification (`is_confidently_aborted_lock_contention`), the knob policy, and
|
|
79
77
|
the loop (`run_with_lock_retry`); both doors into the database run through it —
|
|
80
78
|
`execute_query` for every statement and `call_function` for RPCs (an RPC reaches
|
|
81
|
-
Postgres on a raw connection, bypassing `execute_query` entirely
|
|
82
|
-
deadlock inside any `SECURITY DEFINER` write RPC failed its caller outright).
|
|
79
|
+
Postgres on a raw connection, bypassing `execute_query` entirely).
|
|
83
80
|
`_execute_with_retry` retries only the nothing-was-sent classes above it and must
|
|
84
|
-
never grow a lock budget of its own
|
|
85
|
-
mechanisms landed within hours and nested, making the real ceiling the product of
|
|
86
|
-
two budgets nobody had chosen. Statement-level replay is sound only because both
|
|
81
|
+
never grow a lock budget of its own. Statement-level replay is sound only because both
|
|
87
82
|
doors return early when a `transaction()` is active: every attempt the loop
|
|
88
83
|
retries WAS its own transaction. Inside a caller's transaction the rollback took
|
|
89
84
|
the whole block and only that transaction's owner can redo the unit, so the
|
|
@@ -113,7 +108,9 @@ labels (`unique`, `foreign_key`, `not_null`, `check`, `exclusion`, and
|
|
|
113
108
|
|
|
114
109
|
`UnknownDatabaseError` is reserved for genuinely unrecognized driver failures.
|
|
115
110
|
It is diagnostic and intentionally verbose, so a known PostgreSQL error must
|
|
116
|
-
never reach that fallback.
|
|
111
|
+
never reach that fallback. `AppError.db_sqlstate` preserves the deepest
|
|
112
|
+
PostgreSQL SQLSTATE without retaining traceback frames, so replay-safe transaction
|
|
113
|
+
owners can classify failures without parsing rendered prose.
|
|
117
114
|
|
|
118
115
|
`QueryTimeoutError` diagnoses by SQL verb. A fresh `INSERT` points first to a
|
|
119
116
|
relation/DDL lock convoy, FK parent lock, or trigger work—not same-row fan-out.
|
|
@@ -140,7 +137,17 @@ Static twin: aidream `scripts/check_driver_timeout_vs_statement_ceiling.py`.
|
|
|
140
137
|
`retry_on_transient(..., jitter_ratio=...)` retains deterministic exponential
|
|
141
138
|
backoff by default; a caller recovering a replay-safe lock conflict can add at
|
|
142
139
|
most `jitter_ratio * base_delay` to each retry without changing its retry count
|
|
143
|
-
or exception classification.
|
|
140
|
+
or exception classification. `policy_db=...` instead uses the existing write-retry
|
|
141
|
+
knobs (`1 + max_retries` attempts and their full-jitter backoff), requires explicit
|
|
142
|
+
narrow `retry_on` types, and rejects legacy timing overrides. Resolve policy
|
|
143
|
+
before opening the whole-unit transaction. If a transaction is already active,
|
|
144
|
+
the factory runs once without resolving policy; its outer owner must restart.
|
|
145
|
+
A narrow `RuntimeError` subtype is the caller's assertion of a fixed safe
|
|
146
|
+
structural signal; it does not classify provider failures. Cancellation always
|
|
147
|
+
propagates. Legacy calls retain their original defaults. Transaction/savepoint
|
|
148
|
+
scopes never suppress the body exception; `TransactionContext.__aexit__` returns
|
|
149
|
+
`Literal[False]` or raises, so callers and type checking preserve that fact.
|
|
150
|
+
Guard: `tests/level1/test_resilience_policy.py`.
|
|
144
151
|
|
|
145
152
|
**Read-side connection loss retries once on a fresh checkout.** A read-only SQL
|
|
146
153
|
statement is safe to repeat after `ConnectionDoesNotExistError`. The same retry
|
|
@@ -187,9 +194,7 @@ no timeout, after the one cancellation an outer timeout could deliver was
|
|
|
187
194
|
already spent, and against a hung database that close never ends; (2)
|
|
188
195
|
`asyncpg.create_pool` runs under `pool_create_timeout` (default 30 s) with
|
|
189
196
|
`connect_timeout` (default 10 s), and the half-built pool is terminated on
|
|
190
|
-
failure.
|
|
191
|
-
database machine was hung and held `_locks['matrx_files']` for 4.5 h (the same
|
|
192
|
-
close wedged matrx-seo's keepalive). Pinned by
|
|
197
|
+
failure. Pinned by
|
|
193
198
|
`tests/level1/test_pool_create_never_wedges.py` (a fake PostgreSQL that
|
|
194
199
|
handshakes, then goes silent).
|
|
195
200
|
|
|
@@ -248,9 +253,7 @@ bounds execution, not the WAIT for a lock: a `CREATE TABLE` queued behind a dump
|
|
|
248
253
|
sweep is not executing, so `statement_timeout` never fires and an unbounded waiter
|
|
249
254
|
blocks everyone behind it. `lock_timeout_ms` (default `None` = leave the server
|
|
250
255
|
default) is `SET LOCAL` like the role and the claims, so it cannot outlive the
|
|
251
|
-
transaction.
|
|
252
|
-
(`aidream/services/provisioning/`), whose new tables carry FKs into two of the busiest
|
|
253
|
-
relations on the platform database.
|
|
256
|
+
transaction.
|
|
254
257
|
|
|
255
258
|
**Empty-to-nonempty is not contamination proof.** A READ COMMITTED row can be
|
|
256
259
|
created between the original empty query and its reproof (`guest_executions`
|
|
@@ -271,10 +274,12 @@ column names preserved). A clean answer, empty or not, is proven by that one
|
|
|
271
274
|
statement; a borrowed role RAISES (22P02 naming the role), and only then does
|
|
272
275
|
`repair_guarded_read` emit the contamination alarm and re-read on a pinned, reset
|
|
273
276
|
session. `<login>` is learned once per pool by `learn_login_role` (pinned transaction,
|
|
274
|
-
both resets, `session_user`).
|
|
275
|
-
`EXISTS` proof: 3.5M extra statements in 5.7 h on the live database. A query that
|
|
277
|
+
both resets, `session_user`). A query that
|
|
276
278
|
cannot be wrapped (multi-statement, SHOW, VALUES) keeps the old path
|
|
277
|
-
(`prove_empty_in_one_statement`, then the pinned re-proof).
|
|
279
|
+
(`prove_empty_in_one_statement`, then the pinned re-proof). Replay-safe polling
|
|
280
|
+
reads may explicitly use `verify_empty=False` when their unchanged cursor makes
|
|
281
|
+
an empty-to-nonempty race recover on the next poll. Ordinary reads retain the
|
|
282
|
+
role guard. Pinned by
|
|
278
283
|
`tests/level1/test_guarded_read_never_reruns_empty.py` and `tests/test_pooler_role_guard.py`.
|
|
279
284
|
|
|
280
285
|
**Round trips are the launch cost on a remote pooler.** Every top-level BEGIN sets
|
|
@@ -283,8 +288,7 @@ its ceilings, the host's declared session context and the opener's own settings
|
|
|
283
288
|
role LAST) in ONE `set_config` statement; `set_local_gucs` does the same inside a
|
|
284
289
|
transaction. A transaction-mode pool releases connections with no reset statement
|
|
285
290
|
(`_transaction_pool_release`); a session-mode pool keeps asyncpg's full reset.
|
|
286
|
-
|
|
287
|
-
trip from a laptop): 435 → ~200 round trips. Pinned by
|
|
291
|
+
Pinned by
|
|
288
292
|
`tests/level1/test_transaction_gucs_one_round_trip.py`,
|
|
289
293
|
`tests/level1/test_transaction_pool_release_sends_nothing.py` and
|
|
290
294
|
`tests/level1/test_rls_session_scope.py`.
|
|
@@ -316,8 +320,7 @@ pooler shares server connections with every client of the same login and never r
|
|
|
316
320
|
one between clients, so a session-level `SET default_transaction_read_only = on` (or
|
|
317
321
|
`SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY`) sent outside a transaction — the
|
|
318
322
|
shape of an ad-hoc "read-only production" helper — leaves that backend read-only for
|
|
319
|
-
everyone
|
|
320
|
-
recurring since 2026-09-12). A transaction-mode pool's connections are
|
|
323
|
+
everyone. A transaction-mode pool's connections are
|
|
321
324
|
`ReadWriteConnection` (`read_write.py`): every top-level BEGIN naming no access mode is
|
|
322
325
|
sent as `... READ WRITE` (zero extra round trips), and an autocommit statement refused as
|
|
323
326
|
read-only re-runs once inside `BEGIN READ WRITE` with a WARNING naming the cause. An
|
|
@@ -326,18 +329,15 @@ pooler belongs in `BEGIN READ ONLY`, never a session SET. Pinned by
|
|
|
326
329
|
`tests/test_a_read_only_backend_never_refuses_our_writes.py` (loopback `ISOLATED_PG17_DSN`)
|
|
327
330
|
and `tests/level1/test_read_write_declared.py`.
|
|
328
331
|
|
|
329
|
-
**A backend handed over inside another client's transaction never takes our writes.**
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
transaction to the server. The pooler answers our handshake "idle", so asyncpg learns of it
|
|
333
|
-
only from the reply. A statement that comes back inside a transaction this connection never
|
|
334
|
-
opened is the stranger's: rolled back, logged at ERROR with the remedy, re-run once in our own
|
|
332
|
+
**A backend handed over inside another client's transaction never takes our writes.**
|
|
333
|
+
A pooler may hand over an open transaction despite an idle handshake. A statement
|
|
334
|
+
that comes back inside a transaction this connection never opened is the stranger's: rolled back, logged at ERROR with the remedy, re-run once in our own
|
|
335
335
|
`BEGIN READ WRITE … COMMIT` (the rollback undid it, so exactly once). A top-level BEGIN answered
|
|
336
336
|
with 25001 is the same: rolled back and begun again; a second stranger raises
|
|
337
337
|
`InheritedTransactionError` by name. Pinned by
|
|
338
338
|
`tests/test_a_backend_handed_over_mid_transaction_never_takes_our_writes.py`, which runs an
|
|
339
339
|
in-process transaction pooler that never resets its one server connection (loopback
|
|
340
|
-
`ISOLATED_PG17_DSN
|
|
340
|
+
`ISOLATED_PG17_DSN`).
|
|
341
341
|
|
|
342
342
|
**The destructive live proof is loopback-only.**
|
|
343
343
|
`tests/live_pooler_role.py::assert_isolated_pooler_target` runs before DSN
|
|
@@ -365,9 +365,7 @@ key through its own `server_settings`.
|
|
|
365
365
|
Why it is not optional: an open transaction holds its locks (DDL queues behind
|
|
366
366
|
it for the WHOLE database) and pins the cluster xmin horizon, which stops
|
|
367
367
|
autovacuum from reclaiming dead tuples everywhere, not just on the tables that
|
|
368
|
-
session touched.
|
|
369
|
-
minutes; every `CREATE POLICY` on the live database blocked to `lock_timeout`
|
|
370
|
-
while the migration applier told each agent to fix SQL that was correct.
|
|
368
|
+
session touched.
|
|
371
369
|
|
|
372
370
|
**Startup parameters do not survive a pooler.** Supavisor drops non-allowlisted
|
|
373
371
|
startup parameters in both transaction and session mode (measured 2026-08-21:
|
|
@@ -399,12 +397,7 @@ A block that needs more says `SET LOCAL` later and wins.
|
|
|
399
397
|
|
|
400
398
|
Empty in production — these are deployment settings there. The one caller is
|
|
401
399
|
`matrx_orm.pytest_lock_guard`, the pytest11 guard that bounds what a test run may
|
|
402
|
-
do to a
|
|
403
|
-
`platform.reachability` for 77s and stopped production chat on 2026-09-15
|
|
404
|
-
(root-`conftest.py`, the sixth cross-suite hazard). Verified against the live
|
|
405
|
-
database 2026-09-16: `lock_timeout`, `idle_in_transaction_session_timeout` and a
|
|
406
|
-
tagged `application_name` all land through the pooler this way, and the same
|
|
407
|
-
connection asked for them as startup options gets `0` and `"Supavisor"`.
|
|
400
|
+
do to a shared database.
|
|
408
401
|
|
|
409
402
|
**`long_transactions()` names the blocker.** `matrx_orm.long_transactions`
|
|
410
403
|
(async) and `matrx_orm.long_transactions_sql` (a parameter-free SQL string, so
|
|
@@ -416,7 +409,7 @@ can never disagree about who the blocker was.
|
|
|
416
409
|
|
|
417
410
|
Verified against the live database: 2026-08-21.
|
|
418
411
|
|
|
419
|
-
**`probe_server_vitals()` sees the server without the pool.** One FRESH connection
|
|
412
|
+
**`probe_server_vitals(config_name, timeout_s=…)` sees the server without the pool.** One FRESH connection
|
|
420
413
|
with the registered config's own host/user/password/TLS, `select 1` (timed) plus
|
|
421
414
|
one read-only catalog query — client-backend connections vs `max_connections`, lock
|
|
422
415
|
waiters, the oldest running client statement (maintenance roles in
|
|
@@ -424,68 +417,3 @@ waiters, the oldest running client statement (maintenance roles in
|
|
|
424
417
|
deadline, then terminated. It RAISES (`TimeoutError` on a hung server) because
|
|
425
418
|
its caller, a watchdog, counts failures. Never touches the shared pool, which is
|
|
426
419
|
what is exhausted or hung when a watchdog needs to speak.
|
|
427
|
-
|
|
428
|
-
## Change log
|
|
429
|
-
- 2026-10-03: `probe_server_vitals(config_name, timeout_s=)` — fresh-connection server health probe for the aidream database watchdog; verified live (latency 163 ms, 70/240 connections, postmaster start 22:34:55 UTC).
|
|
430
|
-
- 2026-10-01: `ReadWriteConnection` rolls back a stranger's open transaction it was handed (statement reply or 25001 on BEGIN), re-runs our statement in its own transaction, and names a repeat `InheritedTransactionError`.
|
|
431
|
-
- 2026-10-01: `ReadWriteConnection` for transaction-mode pools — every BEGIN declares READ WRITE and a read-only-refused autocommit statement re-runs once in one; a pooled backend another client left read-only at session level no longer fails the platform's writes.
|
|
432
|
-
- 2026-09-30: Fewer round trips per request (agent-launch latency, lane deep): one-statement proof of a clean empty read; ceilings + declared context + `rls_session` settings in ONE BEGIN-time `set_config` statement (`transaction(opening_gucs=)`, `set_local_gucs`, `emit_local_gucs`); transaction-mode pools release with no reset statement. 435 → ~200 round trips on a flashcard launch.
|
|
433
|
-
- 2026-09-30: `statement_ceiling.py` — a driver timeout above the server's statement ceiling is logged once per call site; `SERVER_CEILING` sentinel. ~19 callers passed 60-600 s under the 30 s `postgres` ceiling (the nightly keyword classifier was canceled at 30 s for eight days).
|
|
434
|
-
- 2026-09-12 (later): ONE retry mechanism. Two independent lock-retry
|
|
435
|
-
implementations for the same class landed hours apart — a `LockContentionError`
|
|
436
|
-
+ constant-budget loop inside `execute_query`, and a `TransientTransactionError`
|
|
437
|
-
+ knob-budget loop wrapped around `_execute_with_retry` — and merged into
|
|
438
|
-
nesting. Reconciled to: `LockContentionError` survives (it covers reads and
|
|
439
|
-
55P03 too), the loop lives once in `write_retry.run_with_lock_retry` and is used
|
|
440
|
-
by `execute_query` AND `call_function`, its budget is the `orm.write_retry`
|
|
441
|
-
knob rows (never a constant), and `TransientTransactionError` is deleted.
|
|
442
|
-
- 2026-09-12: A statement Postgres canceled to break a lock collision
|
|
443
|
-
(40P01/40001/55P03) is re-issued on a fresh connection instead of failing the
|
|
444
|
-
caller. Before this it fell to the catch-all as `UnknownDatabaseError` and
|
|
445
|
-
killed the request: four parallel `ai.agent.start` invocations deadlocked on
|
|
446
|
-
`users.user_secrets` and errored a whole workflow run, and a pure `/chat`
|
|
447
|
-
conversation-list READ showed "deadlock detected" to a person.
|
|
448
|
-
- 2026-08-30: Classified server restart/failover rejection during pool checkout
|
|
449
|
-
as retryable connection failure before any caller SQL is sent.
|
|
450
|
-
- 2026-08-24: Recovered read-only disconnects masked by empty-read reproof's
|
|
451
|
-
transaction teardown, while preserving diagnostic handling for unrelated
|
|
452
|
-
interface errors.
|
|
453
|
-
- 2026-08-22: Retried read-only mid-query connection loss once on a fresh
|
|
454
|
-
checkout while preserving no-retry write semantics.
|
|
455
|
-
- 2026-09-11: Replay-safe polling reads may explicitly skip empty-result
|
|
456
|
-
reproof; their unchanged cursor makes an empty-to-nonempty race recover on
|
|
457
|
-
the next poll, avoiding the transaction-pool reproof convoy without relaxing
|
|
458
|
-
the default integrity guard for ordinary reads.
|
|
459
|
-
- 2026-08-22: Preserved the deepest Postgres SQLSTATE on `AppError` as a
|
|
460
|
-
lightweight classification (without retaining traceback frames), so an
|
|
461
|
-
idempotent transactional owner can recover from a database role transition
|
|
462
|
-
without parsing rendered error prose.
|
|
463
|
-
- 2026-08-21: Added the idle-in-transaction ceiling on every pool and the
|
|
464
|
-
`long_transactions` blocker-naming primitive (feedback c72a32ac).
|
|
465
|
-
|
|
466
|
-
- 2026-08-18: Indexed ModelMeta-derived table names so generated models remain
|
|
467
|
-
discoverable by exact schema/table identity.
|
|
468
|
-
- 2026-08-18: Preserved successful query results when asyncpg times out while
|
|
469
|
-
resetting and discarding the released connection.
|
|
470
|
-
- 2026-08-18: Let waiters reuse healthy connections released behind a slow
|
|
471
|
-
serialized-growth handshake.
|
|
472
|
-
- 2026-08-17: Corrected INSERT timeout guidance to identify relation/DDL lock
|
|
473
|
-
convoys before application row contention.
|
|
474
|
-
- 2026-08-17: Required direct before/after role evidence before recording
|
|
475
|
-
contamination; concurrent empty-to-nonempty reads reconcile without a false
|
|
476
|
-
repair-queue row, and session-authorization contamination is reset too.
|
|
477
|
-
- 2026-08-17: Refused destructive pooler-role verification against shared or
|
|
478
|
-
remote databases before any connection is opened.
|
|
479
|
-
- 2026-08-16: Kept the destructive transaction-pool contamination proof out of
|
|
480
|
-
the installable runtime package and isolated it under package tests; the
|
|
481
|
-
operator wrapper is SQL-free and runtime prose no longer resembles an
|
|
482
|
-
executable non-local role mutation.
|
|
483
|
-
- 2026-08-15: Pinned transaction-local RLS role cleanup across success,
|
|
484
|
-
exception, and early-return paths.
|
|
485
|
-
- 2026-08-15: Added first-timeout pool holder census, host alarm seam, tracked raw-pool helper, and bounded cancellation-safe release.
|
|
486
|
-
- 2026-08-14: Public models now render `public.table` SQL targets; bare public
|
|
487
|
-
relation names can no longer disable application logs or write-failure capture.
|
|
488
|
-
- 2026-08-13: Registry, admin, recovery, catalog, and diagnostic identities are now exact `schema.table`; bare names are accepted only as uncached discovery terms and ambiguity fails loudly.
|
|
489
|
-
- 2026-09-25: Pool creation is bounded and a failed connection init aborts instead of awaiting an untimed close.
|
|
490
|
-
- 2026-08-13: Added atomic recovery from a pool left at zero connections after an upstream database restart.
|
|
491
|
-
- 2026-08-09: Pinned positional-mapping hydration for parameter-shaped column names.
|
|
@@ -31,14 +31,12 @@ import asyncio
|
|
|
31
31
|
import logging
|
|
32
32
|
import random
|
|
33
33
|
import re
|
|
34
|
-
from
|
|
34
|
+
from collections.abc import Awaitable, Callable
|
|
35
35
|
|
|
36
36
|
from matrx_orm.exceptions import PoolAcquireTimeoutError, QueryTimeoutError
|
|
37
37
|
|
|
38
38
|
logger = logging.getLogger("matrx_orm.resilience")
|
|
39
39
|
|
|
40
|
-
T = TypeVar("T")
|
|
41
|
-
|
|
42
40
|
# The transient failures that a rolled-back / idempotent unit of work may retry.
|
|
43
41
|
# Both mean "no committed side effect survived": a command-timeout aborts its
|
|
44
42
|
# transaction, a pool-acquire timeout never sent SQL at all.
|
|
@@ -48,14 +46,15 @@ DEFAULT_TRANSIENT: tuple[type[BaseException], ...] = (
|
|
|
48
46
|
)
|
|
49
47
|
|
|
50
48
|
|
|
51
|
-
async def retry_on_transient(
|
|
49
|
+
async def retry_on_transient[T](
|
|
52
50
|
factory: Callable[[], Awaitable[T]],
|
|
53
51
|
*,
|
|
54
52
|
attempts: int = 3,
|
|
55
53
|
base_backoff: float = 0.25,
|
|
56
54
|
jitter_ratio: float = 0.0,
|
|
57
|
-
retry_on: tuple[type[BaseException], ...] =
|
|
55
|
+
retry_on: tuple[type[BaseException], ...] | None = None,
|
|
58
56
|
label: str = "db-unit",
|
|
57
|
+
policy_db: str | None = None,
|
|
59
58
|
) -> T:
|
|
60
59
|
"""Run ``factory()`` and retry it on a transient DB failure.
|
|
61
60
|
|
|
@@ -66,12 +65,47 @@ async def retry_on_transient(
|
|
|
66
65
|
delay, so callers recovering lock contention need not retry in lockstep.
|
|
67
66
|
On the final attempt the original exception propagates unchanged.
|
|
68
67
|
|
|
68
|
+
``policy_db`` opts into existing write-retry knobs instead of legacy timing.
|
|
69
|
+
It requires explicit narrow lock/structural restart types in ``retry_on``.
|
|
70
|
+
A narrow RuntimeError subtype is the caller's assertion of a fixed safe
|
|
71
|
+
structural signal, not a general classifier of provider failures.
|
|
72
|
+
Inside an active transaction the factory runs once without a policy read;
|
|
73
|
+
its outer owner handles restarts.
|
|
74
|
+
|
|
69
75
|
Loud on every retry AND on heal, so a masked slow-query/contention problem
|
|
70
76
|
is never silent — it shows up as a WARNING you can grep, not a swallowed
|
|
71
77
|
hiccup.
|
|
72
78
|
"""
|
|
73
79
|
if jitter_ratio < 0:
|
|
74
80
|
raise ValueError("jitter_ratio must be non-negative")
|
|
81
|
+
policy = None
|
|
82
|
+
if policy_db is not None:
|
|
83
|
+
if (attempts, base_backoff, jitter_ratio) != (3, 0.25, 0.0):
|
|
84
|
+
raise ValueError("policy_db cannot be combined with legacy retry timing options")
|
|
85
|
+
from matrx_orm.core.transaction import get_active_connection
|
|
86
|
+
from matrx_orm.core.write_retry import resolve_policy
|
|
87
|
+
from matrx_orm.exceptions import DatabaseError, LockContentionError
|
|
88
|
+
|
|
89
|
+
if retry_on is None:
|
|
90
|
+
raise ValueError("policy_db requires explicit retry_on exception types")
|
|
91
|
+
if any(
|
|
92
|
+
kind is RuntimeError
|
|
93
|
+
or not issubclass(kind, (LockContentionError, RuntimeError))
|
|
94
|
+
or issubclass(kind, (asyncio.CancelledError, OSError, PermissionError))
|
|
95
|
+
or (
|
|
96
|
+
issubclass(kind, DatabaseError)
|
|
97
|
+
and not issubclass(kind, LockContentionError)
|
|
98
|
+
)
|
|
99
|
+
for kind in retry_on
|
|
100
|
+
):
|
|
101
|
+
raise ValueError("policy_db requires narrow lock or structural restart types")
|
|
102
|
+
# A savepoint retry retains outer locks/snapshot: only its owner may retry.
|
|
103
|
+
if get_active_connection() is not None:
|
|
104
|
+
return await factory()
|
|
105
|
+
policy = await resolve_policy(policy_db)
|
|
106
|
+
attempts = 1 + policy.max_retries
|
|
107
|
+
if retry_on is None:
|
|
108
|
+
retry_on = DEFAULT_TRANSIENT
|
|
75
109
|
last_exc: BaseException | None = None
|
|
76
110
|
for attempt in range(1, attempts + 1):
|
|
77
111
|
try:
|
|
@@ -85,6 +119,8 @@ async def retry_on_transient(
|
|
|
85
119
|
type(last_exc).__name__ if last_exc else "?",
|
|
86
120
|
)
|
|
87
121
|
return result
|
|
122
|
+
except asyncio.CancelledError:
|
|
123
|
+
raise
|
|
88
124
|
except retry_on as exc:
|
|
89
125
|
last_exc = exc
|
|
90
126
|
if attempt >= attempts:
|
|
@@ -96,7 +132,11 @@ async def retry_on_transient(
|
|
|
96
132
|
type(exc).__name__,
|
|
97
133
|
)
|
|
98
134
|
raise
|
|
99
|
-
backoff =
|
|
135
|
+
backoff = (
|
|
136
|
+
policy.backoff_seconds(attempt - 1)
|
|
137
|
+
if policy is not None
|
|
138
|
+
else base_backoff * (2 ** (attempt - 1))
|
|
139
|
+
)
|
|
100
140
|
if jitter_ratio:
|
|
101
141
|
backoff += random.uniform(0.0, backoff * jitter_ratio) # noqa: S311 -- retry desynchronization
|
|
102
142
|
logger.warning(
|
|
@@ -449,7 +449,7 @@ class TransactionContext:
|
|
|
449
449
|
exc_type: type[BaseException] | None,
|
|
450
450
|
exc_val: BaseException | None,
|
|
451
451
|
exc_tb: Any,
|
|
452
|
-
) ->
|
|
452
|
+
) -> Literal[False]:
|
|
453
453
|
conn = _active_connection.get()
|
|
454
454
|
if self._is_savepoint:
|
|
455
455
|
if self._depth_token is not None:
|
|
@@ -190,7 +190,7 @@ async def resolve_policy(config_name: str) -> WriteRetryPolicy:
|
|
|
190
190
|
)
|
|
191
191
|
values = {str(row["key"]): row["value"] for row in rows or []}
|
|
192
192
|
except Exception as exc: # noqa: BLE001 — a knob read must never fail a write
|
|
193
|
-
_announce_degradation(config_name,
|
|
193
|
+
_announce_degradation(config_name, type(exc).__name__)
|
|
194
194
|
policy = STARTING_POLICY
|
|
195
195
|
else:
|
|
196
196
|
missing = [
|