matrx-orm 3.1.211__tar.gz → 3.1.213__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) hide show
  1. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/PKG-INFO +1 -1
  2. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/__init__.py +2 -0
  3. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/diagnostics.py +74 -0
  4. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/package_wiring.py +37 -4
  5. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/pyproject.toml +1 -6
  6. matrx_orm-3.1.213/tests/test_package_wiring_views.py +46 -0
  7. matrx_orm-3.1.211/matrx_orm/matrx_orm_production_door.pth +0 -3
  8. matrx_orm-3.1.211/matrx_orm/pytest_live_db_guard.py +0 -272
  9. matrx_orm-3.1.211/matrx_orm/pytest_production_door.py +0 -428
  10. matrx_orm-3.1.211/tests/session/test_live_db_guard_plugin.py +0 -210
  11. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/.gitignore +0 -0
  12. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/AGENTS.md +0 -0
  13. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/BASE_CLASS_METHODS.md +0 -0
  14. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/CHANGELOG.md +0 -0
  15. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/CLAUDE.md +0 -0
  16. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/MODEL_API.md +0 -0
  17. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/README.md +0 -0
  18. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/database/orm/extended/managers/ai_model_base.py +0 -0
  19. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/docs/migrations.md +0 -0
  20. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/FEATURE.md +0 -0
  21. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/MODULE_README.md +0 -0
  22. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/adapters/MODULE_README.md +0 -0
  23. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/adapters/__init__.py +0 -0
  24. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/adapters/async_postgresql.py +0 -0
  25. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/adapters/base_adapter.py +0 -0
  26. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/adapters/postgrest_client_adapter.py +0 -0
  27. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/adapters/supabase_adapter.py +0 -0
  28. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/admin/FEATURE.md +0 -0
  29. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/admin/__init__.py +0 -0
  30. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/admin/router.py +0 -0
  31. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/api/__init__.py +0 -0
  32. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/api/auth.py +0 -0
  33. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/api/config.py +0 -0
  34. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/api/handlers.py +0 -0
  35. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/api/protocol.py +0 -0
  36. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/api/server.py +0 -0
  37. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/associations.py +0 -0
  38. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/cache_debug.py +0 -0
  39. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/catalog.py +0 -0
  40. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/catalog_sql.py +0 -0
  41. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/client/MODULE_README.md +0 -0
  42. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/client/__init__.py +0 -0
  43. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/client/postgres_connection.py +0 -0
  44. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/client/postgrest.py +0 -0
  45. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/client/supabase_auth.py +0 -0
  46. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/client/supabase_config.py +0 -0
  47. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/client/supabase_manager.py +0 -0
  48. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/EXTENDED-TASK.md +0 -0
  49. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/FEATURE.md +0 -0
  50. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/MODULE_README.md +0 -0
  51. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/RELATIONS-TASKS.md +0 -0
  52. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/TASKS.md +0 -0
  53. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/__init__.py +0 -0
  54. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/admin_lane.py +0 -0
  55. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/async_db_manager.py +0 -0
  56. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/base.py +0 -0
  57. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/config.py +0 -0
  58. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/connections.py +0 -0
  59. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/db_function.py +0 -0
  60. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/expressions.py +0 -0
  61. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/extended.py +0 -0
  62. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/fields.py +0 -0
  63. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/introspection.py +0 -0
  64. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/listen.py +0 -0
  65. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/loop_filters.py +0 -0
  66. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/model_dto.py +0 -0
  67. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/model_view.py +0 -0
  68. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/one_database.py +0 -0
  69. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/paginator.py +0 -0
  70. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/pool_maintenance.py +0 -0
  71. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/pool_watch.py +0 -0
  72. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/pooler_role.py +0 -0
  73. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/pydantic_bridge.py +0 -0
  74. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/read_write.py +0 -0
  75. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/registry.py +0 -0
  76. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/relations.py +0 -0
  77. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/resilience.py +0 -0
  78. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/rls_session.py +0 -0
  79. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/session_context.py +0 -0
  80. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/signals.py +0 -0
  81. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/statement_ceiling.py +0 -0
  82. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/tls.py +0 -0
  83. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/transaction.py +0 -0
  84. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/types.py +0 -0
  85. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/write_queue.py +0 -0
  86. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/core/write_retry.py +0 -0
  87. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/entity.py +0 -0
  88. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/error_handling.py +0 -0
  89. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/exceptions.py +0 -0
  90. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/extended/__init__.py +0 -0
  91. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/extended/app_error_handler.py +0 -0
  92. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/identity_rule.py +0 -0
  93. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/local_sqlite.py +0 -0
  94. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/middleware/__init__.py +0 -0
  95. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/middleware/base.py +0 -0
  96. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/MODULE_README.md +0 -0
  97. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/__init__.py +0 -0
  98. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/cli.py +0 -0
  99. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/ddl.py +0 -0
  100. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/diff.py +0 -0
  101. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/executor.py +0 -0
  102. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/integration.py +0 -0
  103. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/loader.py +0 -0
  104. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/operations.py +0 -0
  105. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/state.py +0 -0
  106. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/migrations/table_filter.py +0 -0
  107. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/no_org_assignment.py +0 -0
  108. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/FEATURE.md +0 -0
  109. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/MODULE_README.md +0 -0
  110. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/__init__.py +0 -0
  111. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/bulk_update_values.py +0 -0
  112. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/catalog_select.py +0 -0
  113. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/conflict.py +0 -0
  114. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/conflict_writes.py +0 -0
  115. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/create.py +0 -0
  116. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/db_functions.py +0 -0
  117. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/delete.py +0 -0
  118. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/dynamic_admin.py +0 -0
  119. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/dynamic_crud.py +0 -0
  120. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/graph_walk.py +0 -0
  121. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/latest_rows.py +0 -0
  122. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/queue_claim.py +0 -0
  123. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/read.py +0 -0
  124. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/relational_backfill.py +0 -0
  125. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/staging_load.py +0 -0
  126. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/operations/update.py +0 -0
  127. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/platform_access.py +0 -0
  128. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/platform_db.py +0 -0
  129. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/py.typed +0 -0
  130. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/pytest_lock_guard.py +0 -0
  131. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/pytest_plugin.py +0 -0
  132. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/python_sql/MODULE_README.md +0 -0
  133. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/python_sql/__init__.py +0 -0
  134. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/python_sql/db_objects.py +0 -0
  135. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/python_sql/table_detailed_relationships.py +0 -0
  136. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/python_sql/table_typescript_relationship.py +0 -0
  137. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/query/FEATURE.md +0 -0
  138. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/query/MODULE_README.md +0 -0
  139. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/query/__init__.py +0 -0
  140. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/query/builder.py +0 -0
  141. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/query/executor.py +0 -0
  142. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/resources/__init__.py +0 -0
  143. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/resources/additional-assigners-2026-09-12.json +0 -0
  144. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/resources/org_assignment_trigger_baseline.json +0 -0
  145. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/FEATURE.md +0 -0
  146. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/MODULE_README.md +0 -0
  147. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/__init__.py +0 -0
  148. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/code_handler.py +0 -0
  149. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/codegen_writer.py +0 -0
  150. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/columns.py +0 -0
  151. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/common.py +0 -0
  152. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/diff_preview.py +0 -0
  153. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/entity_capabilities.py +0 -0
  154. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/excluded_targets.py +0 -0
  155. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/generator.py +0 -0
  156. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/helpers/__init__.py +0 -0
  157. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/helpers/base_generators.py +0 -0
  158. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/helpers/entity_generators.py +0 -0
  159. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/helpers/git_checker.py +0 -0
  160. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/relationships.py +0 -0
  161. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/runner.py +0 -0
  162. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/schema.py +0 -0
  163. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/schema_manager.py +0 -0
  164. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/tables.py +0 -0
  165. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/schema_builder/views.py +0 -0
  166. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/FEATURE.md +0 -0
  167. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/__init__.py +0 -0
  168. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/attachments.py +0 -0
  169. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/backup_restore.py +0 -0
  170. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/crypto.py +0 -0
  171. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/host_authorization.py +0 -0
  172. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/items.py +0 -0
  173. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/model.py +0 -0
  174. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/mutation_receipts.py +0 -0
  175. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/native_enable.py +0 -0
  176. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/native_lifecycle.py +0 -0
  177. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/native_passkeys.py +0 -0
  178. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/native_source.py +0 -0
  179. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/org_service.py +0 -0
  180. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/org_vault_gate.py +0 -0
  181. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/service.py +0 -0
  182. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/secrets_battery/vault_history.py +0 -0
  183. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/README.md +0 -0
  184. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/__init__.py +0 -0
  185. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/coalesce.py +0 -0
  186. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/dag.py +0 -0
  187. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/errors.py +0 -0
  188. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/fallback.py +0 -0
  189. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/flush.py +0 -0
  190. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/lifecycle.py +0 -0
  191. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/managed.py +0 -0
  192. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/op.py +0 -0
  193. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/reads.py +0 -0
  194. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/session.py +0 -0
  195. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/session/telemetry.py +0 -0
  196. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/sql_executor/MODULE_README.md +0 -0
  197. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/sql_executor/__init__.py +0 -0
  198. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/sql_executor/executor.py +0 -0
  199. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/sql_executor/queries.py +0 -0
  200. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/sql_executor/registry.py +0 -0
  201. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/sql_executor/types.py +0 -0
  202. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/sql_executor/utils.py +0 -0
  203. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/state.py +0 -0
  204. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/utils/__init__.py +0 -0
  205. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/utils/sql_utils.py +0 -0
  206. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/utils/type_converters.py +0 -0
  207. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/matrx_orm/write_actor.py +0 -0
  208. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/scripts/git-branches.sh +0 -0
  209. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/scripts/publish.sh +0 -0
  210. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/scripts/release.sh +0 -0
  211. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/MODULE_README.md +0 -0
  212. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/__init__.py +0 -0
  213. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/conftest.py +0 -0
  214. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/MODULE_README.md +0 -0
  215. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/__init__.py +0 -0
  216. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_adapter_registry.py +0 -0
  217. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_admin_db_columns.py +0 -0
  218. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_admin_response_rendering.py +0 -0
  219. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_admin_search_negation.py +0 -0
  220. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_admin_search_sentinels.py +0 -0
  221. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_advisory_lock.py +0 -0
  222. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_agent_message.py +0 -0
  223. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_api_auth.py +0 -0
  224. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_api_config.py +0 -0
  225. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_api_handlers.py +0 -0
  226. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_api_protocol.py +0 -0
  227. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_array_agg_order_by.py +0 -0
  228. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_association_trigger_actor_naming.py +0 -0
  229. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_associations.py +0 -0
  230. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_associations_wiring.py +0 -0
  231. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_bulk_hydration_offload.py +0 -0
  232. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_bulk_update_by_pk.py +0 -0
  233. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_bulk_upsert_increment_set_fields.py +0 -0
  234. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_cache_debug.py +0 -0
  235. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_call_function.py +0 -0
  236. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_case_when.py +0 -0
  237. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_catalog.py +0 -0
  238. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_column_scoped_writes.py +0 -0
  239. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_committed_row_guard.py +0 -0
  240. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_composite_pk_filter.py +0 -0
  241. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_composite_pk_write_paths.py +0 -0
  242. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_config.py +0 -0
  243. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_conflict_target.py +0 -0
  244. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_conflict_writes.py +0 -0
  245. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_connection_codecs.py +0 -0
  246. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_connection_poison_guard.py +0 -0
  247. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_connection_primitives.py +0 -0
  248. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_count_composite_distinct.py +0 -0
  249. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_count_limit_param_leak.py +0 -0
  250. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_db_function_field.py +0 -0
  251. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_ddl_generator.py +0 -0
  252. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_deadlock_retry.py +0 -0
  253. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_derived_table.py +0 -0
  254. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_dirty_tracking.py +0 -0
  255. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_dynamic_crud.py +0 -0
  256. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_exceptions.py +0 -0
  257. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_execute_query_integrity_mapping.py +0 -0
  258. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_expression_primitives.py +0 -0
  259. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_fields.py +0 -0
  260. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_filter_jsonb_agg_array_index.py +0 -0
  261. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_fk_cycle_resolution.py +0 -0
  262. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_from_alias.py +0 -0
  263. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_fts.py +0 -0
  264. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_func_expression_args.py +0 -0
  265. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_graph_walk.py +0 -0
  266. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_having_annotate_alias.py +0 -0
  267. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_insert_ignore_and_admin_primitives.py +0 -0
  268. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_introspect_rls_policies.py +0 -0
  269. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_join_and_aggregate.py +0 -0
  270. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_latest_rows.py +0 -0
  271. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_listen_notify.py +0 -0
  272. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_local_sqlite.py +0 -0
  273. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_lock_contention_retry.py +0 -0
  274. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_managed_write_guard.py +0 -0
  275. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_matrx_entity.py +0 -0
  276. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_migration_diff_types.py +0 -0
  277. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_migration_loader.py +0 -0
  278. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_model_instance.py +0 -0
  279. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_model_meta.py +0 -0
  280. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_optimistic_concurrency.py +0 -0
  281. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_order_by_expression.py +0 -0
  282. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_org_assignment_inventory.py +0 -0
  283. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_orm_banners_are_client_safe.py +0 -0
  284. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_parameter_name_hydration.py +0 -0
  285. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_patch_jsonb_path.py +0 -0
  286. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_percentile_cont.py +0 -0
  287. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_persisted_count.py +0 -0
  288. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_person_scoped_session_bypasses_shared_cache.py +0 -0
  289. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_pool_create_never_wedges.py +0 -0
  290. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_pool_holder_census.py +0 -0
  291. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_pool_loop_recreation.py +0 -0
  292. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_pool_maintenance.py +0 -0
  293. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_postgrest_filters.py +0 -0
  294. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_pydantic_bridge.py +0 -0
  295. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_query_builder.py +0 -0
  296. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_query_error_detail.py +0 -0
  297. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_query_executor_sql.py +0 -0
  298. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_query_timeout.py +0 -0
  299. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_querybuilder_clone_semantics.py +0 -0
  300. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_queue_claim.py +0 -0
  301. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_read_connection_retry.py +0 -0
  302. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_read_write_declared.py +0 -0
  303. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_registry.py +0 -0
  304. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_registry_multi_database.py +0 -0
  305. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_registry_multi_schema.py +0 -0
  306. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_relational_backfill.py +0 -0
  307. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_relations.py +0 -0
  308. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_resilience.py +0 -0
  309. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_rls_session_scope.py +0 -0
  310. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_schema_exists.py +0 -0
  311. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_session_advisory_lock.py +0 -0
  312. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_standalone_write_session_context.py +0 -0
  313. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_state_cache.py +0 -0
  314. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_subquery_filter_raw.py +0 -0
  315. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_subquery_in_filter.py +0 -0
  316. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_subquery_nested_expressions.py +0 -0
  317. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_supabase_auth.py +0 -0
  318. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_supabase_config.py +0 -0
  319. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_tls.py +0 -0
  320. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_transaction_database_identity.py +0 -0
  321. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_transaction_gucs_one_round_trip.py +0 -0
  322. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_transaction_pool_release_sends_nothing.py +0 -0
  323. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_typed_join_projection.py +0 -0
  324. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_typed_predicates.py +0 -0
  325. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_update_case_expression.py +0 -0
  326. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_update_subquery.py +0 -0
  327. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_update_with_rebase.py +0 -0
  328. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_upsert_default_leak.py +0 -0
  329. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_upsert_with_conflict.py +0 -0
  330. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_values_jsonb_decode.py +0 -0
  331. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_watched_lifecycle.py +0 -0
  332. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_write_queue_deadline.py +0 -0
  333. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level1/test_write_retry_semantics.py +0 -0
  334. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/MODULE_README.md +0 -0
  335. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/__init__.py +0 -0
  336. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/conftest.py +0 -0
  337. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_bulk_ops.py +0 -0
  338. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_cache_integration.py +0 -0
  339. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_crud.py +0 -0
  340. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_foreign_keys.py +0 -0
  341. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_m2m.py +0 -0
  342. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_manager.py +0 -0
  343. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_migrations_live.py +0 -0
  344. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_query_execution.py +0 -0
  345. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/test_schema_diff.py +0 -0
  346. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/level2/verify_committed_row_guard_pg17.py +0 -0
  347. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/live_pooler_role.py +0 -0
  348. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/native_source_cases.py +0 -0
  349. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/native_source_oracle.rs +0 -0
  350. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project/.env.example +0 -0
  351. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project/README.md +0 -0
  352. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project/__init__.py +0 -0
  353. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project/generate.py +0 -0
  354. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project/generated/.gitkeep +0 -0
  355. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project/matrx_orm.yaml +0 -0
  356. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project/test_schema_generation.py +0 -0
  357. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project_desktop/.env.example +0 -0
  358. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project_desktop/README.md +0 -0
  359. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project_desktop/__init__.py +0 -0
  360. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project_desktop/client_example.py +0 -0
  361. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project_desktop/client_example.ts +0 -0
  362. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project_desktop/client_supabase_example.py +0 -0
  363. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/sample_project_desktop/server.py +0 -0
  364. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/entity_tests.py +0 -0
  365. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_base_generation.py +0 -0
  366. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_composite_pk_fk_generation.py +0 -0
  367. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_composite_unique_generation.py +0 -0
  368. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_dto_identity_generation.py +0 -0
  369. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_entity_capability_generation.py +0 -0
  370. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_enum_ordering.py +0 -0
  371. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_excluded_fk_targets.py +0 -0
  372. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_generate_schema.py +0 -0
  373. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_junction_analysis.py +0 -0
  374. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_multi_schema_output.py +0 -0
  375. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_schema_analysis.py +0 -0
  376. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_sql_expression_defaults.py +0 -0
  377. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_table_relationships_query.py +0 -0
  378. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema/test_view_generation.py +0 -0
  379. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema_builder/test_array_default_parsing.py +0 -0
  380. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema_builder/test_focused_generation_plan.py +0 -0
  381. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema_builder/test_host_models_aggregator.py +0 -0
  382. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/schema_builder/test_never_filter_columns.py +0 -0
  383. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/__init__.py +0 -0
  384. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/conftest.py +0 -0
  385. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_a_failed_capture_still_names_the_failure.py +0 -0
  386. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_cache_no_downgrade.py +0 -0
  387. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_capture_poison_proof.py +0 -0
  388. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_coalesce.py +0 -0
  389. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_dag.py +0 -0
  390. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_disk_spill_fallback.py +0 -0
  391. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_flush_individual_fallback.py +0 -0
  392. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_governed_write.py +0 -0
  393. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_managed.py +0 -0
  394. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_op_enqueue_site.py +0 -0
  395. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_reads.py +0 -0
  396. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_record_error_bounded_insert.py +0 -0
  397. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_record_error_storm.py +0 -0
  398. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_session.py +0 -0
  399. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/session/test_spill_guard_plugin.py +0 -0
  400. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_a_backend_handed_over_mid_transaction_never_takes_our_writes.py +0 -0
  401. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_a_list_of_uuids_binds_as_uuid_array.py +0 -0
  402. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_a_read_only_backend_never_refuses_our_writes.py +0 -0
  403. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_a_sealed_field_shows_no_character_of_its_value.py +0 -0
  404. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_array_arg_element_type.py +0 -0
  405. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_attachment_mutation_serialization.py +0 -0
  406. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_backup_alias_conflict.py +0 -0
  407. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_backup_history_restore.py +0 -0
  408. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_backup_restore_live.py +0 -0
  409. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_call_function_as.py +0 -0
  410. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_call_function_none_mode.py +0 -0
  411. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_composite_fk_is_not_a_column_fk.py +0 -0
  412. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_database_name_alias.py +0 -0
  413. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_db_functions.py +0 -0
  414. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_dsn_password_masking.py +0 -0
  415. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_dynamic_select_unregistered.py +0 -0
  416. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_immutable_insert_or_exact_verify.py +0 -0
  417. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_keyed_digest.py +0 -0
  418. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_model_cls_refactor.py +0 -0
  419. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_native_enable.py +0 -0
  420. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_native_lifecycle.py +0 -0
  421. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_native_lifecycle_fences.py +0 -0
  422. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_native_passkey_receipts.py +0 -0
  423. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_native_source.py +0 -0
  424. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_no_blocking_asyncpg_tls.py +0 -0
  425. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_one_database.py +0 -0
  426. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_order_by_desc_nulls_last.py +0 -0
  427. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_org_vault_gate.py +0 -0
  428. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_pooler_role_guard.py +0 -0
  429. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_secret_audit_names_its_organization.py +0 -0
  430. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_secrets_battery.py +0 -0
  431. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_secrets_minting_keys.py +0 -0
  432. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_shared_lock_guard.py +0 -0
  433. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_sql_param_casts.py +0 -0
  434. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_statement_ceiling_warning.py +0 -0
  435. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_sync_twins_guard.py +0 -0
  436. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_update_result_truthiness.py +0 -0
  437. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/tests/test_user_visible_lookup.py +0 -0
  438. {matrx_orm-3.1.211 → matrx_orm-3.1.213}/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.211
3
+ Version: 3.1.213
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
@@ -73,6 +73,7 @@ from .core.diagnostics import (
73
73
  log_pool_diagnostics,
74
74
  long_transactions,
75
75
  long_transactions_sql,
76
+ probe_server_vitals,
76
77
  )
77
78
  from .core.introspection import (
78
79
  introspect_column_shapes,
@@ -474,6 +475,7 @@ __all__ = [
474
475
  "LONG_TRANSACTION_SECONDS",
475
476
  "long_transactions",
476
477
  "long_transactions_sql",
478
+ "probe_server_vitals",
477
479
  "describe_transaction",
478
480
  "describe_transactions",
479
481
  "install_asyncpg_idle_close_filter",
@@ -339,3 +339,77 @@ async def introspect_lock_waits(
339
339
  int(query_chars),
340
340
  )
341
341
  return [dict(r) for r in rows]
342
+
343
+
344
+ # ── Out-of-band server vitals ────────────────────────────────────────────────
345
+ #
346
+ # A watchdog that must notice the database being DOWN cannot borrow a pool
347
+ # connection: the pool is exactly what is exhausted or hung when it matters.
348
+ # ``probe_server_vitals`` opens ONE fresh connection with the registered
349
+ # config's own parameters (host, port, user, password, TLS), runs ``select 1``
350
+ # (timed) and one read-only catalog query, and closes it — the whole thing
351
+ # under one deadline, so a hung server is a ``TimeoutError``, never a hang.
352
+
353
+ _SERVER_VITALS_SQL = """
354
+ SELECT
355
+ (SELECT count(*) FROM pg_stat_activity)::int AS connections,
356
+ current_setting('max_connections')::int AS max_connections,
357
+ (SELECT count(*) FROM pg_stat_activity WHERE wait_event_type = 'Lock')::int AS lock_waiters,
358
+ COALESCE((
359
+ SELECT max(EXTRACT(EPOCH FROM (clock_timestamp() - query_start)))
360
+ FROM pg_stat_activity
361
+ WHERE state = 'active'
362
+ AND backend_type = 'client backend'
363
+ AND pid <> pg_backend_pid()
364
+ AND query_start IS NOT NULL
365
+ ), 0)::float8 AS longest_active_seconds,
366
+ pg_postmaster_start_time() AS postmaster_started_at
367
+ """
368
+
369
+
370
+ async def probe_server_vitals(config_name: str, *, timeout_s: float) -> dict[str, Any]:
371
+ """One fresh, short-lived connection's view of the server's health.
372
+
373
+ Returns ``latency_ms`` (the ``select 1`` round trip), ``connections``,
374
+ ``max_connections``, ``lock_waiters``, ``longest_active_seconds`` (the
375
+ oldest running client statement, excluding this probe and replication)
376
+ and ``postmaster_started_at`` (a change means the server restarted).
377
+
378
+ Read-only. Never touches the shared pool. RAISES on any failure —
379
+ including ``TimeoutError`` when connect + both queries exceed
380
+ ``timeout_s`` — because the caller's whole job is to count failures.
381
+ """
382
+ import asyncio
383
+ import time
384
+
385
+ import asyncpg
386
+
387
+ from matrx_orm.core.tls import resolve_asyncpg_ssl
388
+
389
+ config = get_database_config(config_name)
390
+ ssl = await resolve_asyncpg_ssl(config.get("ssl", "require"))
391
+
392
+ async def _run() -> dict[str, Any]:
393
+ conn = await asyncpg.connect(
394
+ host=config["host"],
395
+ port=config["port"],
396
+ database=config["database_name"],
397
+ user=config["user"],
398
+ password=config["password"],
399
+ ssl=ssl,
400
+ timeout=timeout_s,
401
+ statement_cache_size=0,
402
+ server_settings={"application_name": "matrx_server_vitals_probe"},
403
+ )
404
+ try:
405
+ started = time.perf_counter()
406
+ await conn.fetchval("SELECT 1")
407
+ latency_ms = (time.perf_counter() - started) * 1000.0
408
+ row = await conn.fetchrow(_SERVER_VITALS_SQL)
409
+ finally:
410
+ conn.terminate()
411
+ result = dict(row) if row is not None else {}
412
+ result["latency_ms"] = round(latency_ms, 1)
413
+ return result
414
+
415
+ return await asyncio.wait_for(_run(), timeout=timeout_s)
@@ -179,8 +179,36 @@ def _lookup(inventory: dict[tuple[str, str], TableInfo], table: str) -> TableInf
179
179
  return info
180
180
 
181
181
 
182
+ def _lookup_view(
183
+ inventory: dict[tuple[str, str], TableInfo], view: str, python_root: str | Path | None
184
+ ) -> TableInfo:
185
+ if "." not in view:
186
+ raise PackageWiringError(f"package_wiring: view '{view}' must be '<schema>.<snake>'")
187
+ schema, snake = view.split(".", 1)
188
+ sibling = next((i for (s, _), i in inventory.items() if s == schema), None)
189
+ if sibling is None:
190
+ raise PackageWiringError(
191
+ f"package_wiring: view '{view}' — schema '{schema}' has no generated models module"
192
+ )
193
+ from matrx_orm.schema_builder.common import dt_utils, safe_model_class_name
194
+
195
+ pascal = safe_model_class_name(snake, schema, dt_utils.to_pascal_case)
196
+ if python_root is not None:
197
+ models_file = Path(python_root) / (sibling.models_module.replace(".", "/") + ".py")
198
+ tree = ast.parse(models_file.read_text(), filename=str(models_file))
199
+ if not any(isinstance(n, ast.ClassDef) and n.name == pascal for n in tree.body):
200
+ raise PackageWiringError(
201
+ f"package_wiring: view '{view}' has no generated class {pascal} in "
202
+ f"{models_file} — is the view in the schema and its view_primary_keys declared?"
203
+ )
204
+ return TableInfo(schema=schema, snake=snake, pascal=pascal, models_module=sibling.models_module)
205
+
206
+
182
207
  def resolve_manifest(
183
- name: str, req: dict[str, Any], inventory: dict[tuple[str, str], TableInfo]
208
+ name: str,
209
+ req: dict[str, Any],
210
+ inventory: dict[tuple[str, str], TableInfo],
211
+ python_root: str | Path | None = None,
184
212
  ) -> ResolvedPackage:
185
213
  target = req.get("target") or {}
186
214
  configure_import = target.get("configure_import")
@@ -225,9 +253,14 @@ def resolve_manifest(
225
253
  )
226
254
  )
227
255
 
228
- # Explicit models.
256
+ # Explicit models. A VIEW has a generated model class but no auto_config entry, so a
257
+ # manifest names it with "view" instead of "table"; it resolves by the generator's own
258
+ # class-naming rule and must exist in the schema's generated models file.
229
259
  for entry in req.get("models") or []:
230
- info = _lookup(inventory, entry["table"])
260
+ if "view" in entry:
261
+ info = _lookup_view(inventory, entry["view"], python_root)
262
+ else:
263
+ info = _lookup(inventory, entry["table"])
231
264
  assignments.append(Assignment("models", entry["key"], info.models_module, info.pascal))
232
265
 
233
266
  # Explicit bases.
@@ -421,7 +454,7 @@ def _resolve_all(cfg: dict[str, Any], python_root: str) -> tuple[str, list[Resol
421
454
  f"package_wiring.packages entry needs 'name' and 'manifest_path': {entry}"
422
455
  )
423
456
  req = _load_manifest(Path(python_root) / manifest_path)
424
- packages.append(resolve_manifest(name, req, inventory))
457
+ packages.append(resolve_manifest(name, req, inventory, python_root))
425
458
  return output_module, packages
426
459
 
427
460
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "matrx-orm"
3
- version = "3.1.211"
3
+ version = "3.1.213"
4
4
  description = "Async-first PostgreSQL ORM with bidirectional migrations, schema introspection, many-to-many relationships, and built-in state caching"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -51,8 +51,6 @@ dependencies = [
51
51
  [project.entry-points.pytest11]
52
52
  matrx_write_spill_guard = "matrx_orm.pytest_plugin"
53
53
  matrx_shared_lock_guard = "matrx_orm.pytest_lock_guard"
54
- matrx_live_db_guard = "matrx_orm.pytest_live_db_guard"
55
- matrx_production_door = "matrx_orm.pytest_production_door"
56
54
 
57
55
  [project.urls]
58
56
  Homepage = "https://github.com/AI-Matrix-Engine/aidream-current"
@@ -84,9 +82,6 @@ dev = [
84
82
  packages = ["matrx_orm"]
85
83
  include = ["matrx_orm/py.typed", "matrx_orm/resources/*.json"]
86
84
 
87
- [tool.hatch.build.targets.wheel.force-include]
88
- "matrx_orm/matrx_orm_production_door.pth" = "matrx_orm_production_door.pth"
89
-
90
85
  [tool.hatch.metadata]
91
86
  allow-direct-references = true
92
87
 
@@ -0,0 +1,46 @@
1
+ """A manifest may wire a VIEW: views get a generated model class but no auto_config entry."""
2
+
3
+ from pathlib import Path
4
+
5
+ import pytest
6
+
7
+ from matrx_orm.schema_builder.package_wiring import (
8
+ PackageWiringError,
9
+ TableInfo,
10
+ resolve_manifest,
11
+ )
12
+
13
+ INVENTORY = {("ai", "setting"): TableInfo("ai", "setting", "Setting", "db.models.ai")}
14
+
15
+
16
+ def _req(entry):
17
+ return {"target": {"configure_import": "x", "configure_call": "configure"}, "models": [entry]}
18
+
19
+
20
+ def _root(tmp_path: Path, classes: str) -> Path:
21
+ (tmp_path / "db" / "models").mkdir(parents=True)
22
+ (tmp_path / "db" / "models" / "ai.py").write_text(classes)
23
+ return tmp_path
24
+
25
+
26
+ def test_a_view_resolves_to_its_generated_class(tmp_path):
27
+ root = _root(tmp_path, "class Setting: pass\nclass OfferingRulesCompiled: pass\n")
28
+ pkg = resolve_manifest(
29
+ "p", _req({"key": "AiOfferingRulesCompiled", "view": "ai.offering_rules_compiled"}),
30
+ INVENTORY, root,
31
+ )
32
+ [a] = [x for x in pkg.assignments if x.key == "AiOfferingRulesCompiled"]
33
+ assert (a.module, a.symbol) == ("db.models.ai", "OfferingRulesCompiled")
34
+
35
+
36
+ def test_a_view_without_a_generated_class_is_refused(tmp_path):
37
+ root = _root(tmp_path, "class Setting: pass\n")
38
+ with pytest.raises(PackageWiringError, match="no generated class OfferingRulesCompiled"):
39
+ resolve_manifest(
40
+ "p", _req({"key": "K", "view": "ai.offering_rules_compiled"}), INVENTORY, root
41
+ )
42
+
43
+
44
+ def test_a_table_entry_naming_a_view_is_still_refused():
45
+ with pytest.raises(PackageWiringError, match="not in the host inventory"):
46
+ resolve_manifest("p", _req({"key": "K", "table": "ai.offering_rules_compiled"}), INVENTORY)
@@ -1,3 +0,0 @@
1
- # Installed by matrx-orm: in a process whose environment carries MATRX_PRODUCTION_DOOR=1 (exported by the
2
- # pytest plugin matrx_orm.pytest_production_door), install the same production door before any user code.
3
- import os; exec("import sys, importlib.util as u, importlib.machinery as m\ns = m.PathFinder.find_spec('matrx_orm')\nif s and s.submodule_search_locations and 'matrx_orm.pytest_production_door' not in sys.modules:\n sp = u.spec_from_file_location('matrx_orm.pytest_production_door', list(s.submodule_search_locations)[0] + '/pytest_production_door.py')\n mod = u.module_from_spec(sp); sys.modules[sp.name] = mod; sp.loader.exec_module(mod); mod.install()") if os.environ.get("MATRX_PRODUCTION_DOOR") == "1" else None
@@ -1,272 +0,0 @@
1
- """Session-wide guard: a test run never reaches the LIVE platform database by accident.
2
-
3
- Registered as a ``pytest11`` entry point, so pytest loads it in every suite regardless of
4
- rootdir — the same mechanism as the spill guard (``matrx_orm.pytest_plugin``) and the lock
5
- guard (``matrx_orm.pytest_lock_guard``). This is the SEVENTH cross-suite hazard; the other six
6
- are catalogued in the aidream repo-root ``conftest.py``.
7
-
8
- WHY IT EXISTS (lane INTEG-SERVER, 2026-09-24). A developer's ``.env`` holds the five
9
- ``SUPABASE_MATRIX_*`` variables for the LIVE database, because that is what the server runs
10
- on. Those variables SELECT a connection; they never AUTHORISED one. So every suite that
11
- imports the host's ``db`` package — ``aidream/services/agent_data/tests/test_rls_data_access.py``
12
- creates, edits and HARD-deletes notes — ran against production whenever it was collected,
13
- with nobody having decided that. The matrx-records suite closed this for itself on 2026-09-22
14
- (a declared target, default the rehearsal branch, main behind three locked doors); this closes
15
- it for every suite, once, in the package that owns the connection.
16
-
17
- THE RULE. Before any test module is imported, the connection the five variables (or the
18
- ``.env`` that will supply them) resolve to is compared with the live database's identity —
19
- its project ref in the pooler user (``postgres.<ref>``) or a live host. When it IS the live
20
- database:
21
-
22
- * **Default:** the five variables are REPOINTED, in this process only, to the rehearsal
23
- branch — ``MATRX_TEST_DATABASE_URL`` when set (any declared non-live target, e.g. the dev
24
- clone), else ``SUPABASE_BRANCH_DATABASE_URL``. With neither, they point at an unreachable
25
- placeholder (``127.0.0.1:1``), so a live test FAILS to connect instead of writing to
26
- production. The banner says which, once.
27
- * **Live, on purpose:** ``--live-db --live-db-reason "<why>"`` inside the 1–4 AM Pacific
28
- maintenance window leaves them alone and prints the reason. The environment cannot open
29
- this door (an exported variable outlives the shell that set it); a missing reason or a
30
- time outside the window is a usage error that stops the session.
31
-
32
- A connection that is NOT the live database — a local Postgres in CI, the branch, the clone —
33
- is never touched. Values are never printed.
34
- """
35
-
36
- from __future__ import annotations
37
-
38
- import os
39
- from datetime import datetime
40
- from urllib.parse import unquote, urlsplit
41
- from zoneinfo import ZoneInfo
42
-
43
- import pytest
44
-
45
- #: The ONE live database (aidream CLAUDE.md), by the identities a connection can carry.
46
- LIVE_PROJECT_REFS = frozenset({"brsgrqvjdzwihsvnfqkf"})
47
- LIVE_HOSTS = frozenset({"db.matrxserver.com", "db.brsgrqvjdzwihsvnfqkf.supabase.co"})
48
-
49
- DB_VARS = (
50
- "SUPABASE_MATRIX_HOST",
51
- "SUPABASE_MATRIX_PORT",
52
- "SUPABASE_MATRIX_USER",
53
- "SUPABASE_MATRIX_PASSWORD",
54
- "SUPABASE_MATRIX_DATABASE_NAME",
55
- )
56
- TARGET_URL_VARS = ("MATRX_TEST_DATABASE_URL", "SUPABASE_BRANCH_DATABASE_URL")
57
- WINDOW_TZ, WINDOW_START, WINDOW_END = "America/Los_Angeles", 1, 4
58
- PLACEHOLDER = {
59
- "SUPABASE_MATRIX_HOST": "127.0.0.1",
60
- "SUPABASE_MATRIX_PORT": "1",
61
- "SUPABASE_MATRIX_USER": "live-db-refused-under-pytest",
62
- "SUPABASE_MATRIX_PASSWORD": "refused",
63
- "SUPABASE_MATRIX_DATABASE_NAME": "refused",
64
- }
65
-
66
- #: THE HTTP ROUTE to the same database (2026-09-27). PostgREST, the admin door and the
67
- #: Management API need no pool: a project URL plus the secret key (or the account access
68
- #: token) reaches production by itself. Under pytest without --live-db, a live URL sends
69
- #: every one of these to an unreachable placeholder too. Names cover the canonical
70
- #: variables and the aliases the host materializes from them.
71
- HTTP_URL_VARS = ("SUPABASE_MATRIX_URL", "SUPABASE_URL")
72
- HTTP_SECRET_VARS = (
73
- "SUPABASE_MATRIX_SECRET_KEY",
74
- "SUPABASE_SECRET_KEY",
75
- "SUPABASE_MATRIX_SERVICE_ROLE_KEY",
76
- "SUPABASE_SERVICE_ROLE_KEY",
77
- "SUPABASE_ACCESS_TOKEN",
78
- )
79
- HTTP_PLACEHOLDER_URL = "http://127.0.0.1:1"
80
- HTTP_PLACEHOLDER_SECRET = "live-http-refused-under-pytest"
81
-
82
-
83
- def is_live_url(url: str) -> bool:
84
- """Does this HTTP URL name the live project?"""
85
- host = (urlsplit((url or "").strip()).hostname or "").lower()
86
- return host in LIVE_HOSTS or any(host.startswith(f"{ref}.") for ref in LIVE_PROJECT_REFS)
87
-
88
-
89
- def decide_http(env: dict[str, str], dotenv: dict[str, str], *, live_flag: bool) -> dict[str, str] | None:
90
- """The HTTP variables to overwrite, or None. Pure — the hook applies it.
91
-
92
- Independent of the pool decision: a CI run on a local Postgres with a live URL
93
- left in .env is exactly the case the pool guard cannot see.
94
- """
95
- if live_flag:
96
- return None
97
- urls = {k: env.get(k) or dotenv.get(k, "") for k in HTTP_URL_VARS}
98
- if not any(is_live_url(u) for u in urls.values()):
99
- return None
100
- out = {k: HTTP_PLACEHOLDER_URL for k in HTTP_URL_VARS}
101
- out.update({k: HTTP_PLACEHOLDER_SECRET for k in HTTP_SECRET_VARS})
102
- return out
103
-
104
-
105
- #: The ONLY accounts a test may act as (workspace law: "use ONLY admin@admin.com, never Arman's
106
- #: personal account"; test@test.com is the non-admin seat). By id, because an id is what a test
107
- #: reads from ``TEST_USER_ID`` and an id cannot be mistaken for a similar email.
108
- TEST_ACCOUNT_IDS = {
109
- "87a6e699-3622-4869-8843-d0867456c0dd": "admin@admin.com",
110
- "4060701e-706a-4c76-b3ca-0bbc69fa5a14": "test@test.com",
111
- }
112
-
113
-
114
- def refuse_a_real_person(env: dict[str, str], dotenv: dict[str, str]) -> None:
115
- """``TEST_USER_ID`` must be one of the test accounts, or the session does not start."""
116
- user = (env.get("TEST_USER_ID") or dotenv.get("TEST_USER_ID") or "").strip()
117
- if user and user not in TEST_ACCOUNT_IDS:
118
- raise pytest.UsageError(
119
- "REFUSED: TEST_USER_ID is not a test account. Tests act ONLY as admin@admin.com "
120
- "(or test@test.com for a non-admin seat) — never a real person's account, and never "
121
- "the owner's personal one. Set TEST_USER_ID to admin@admin.com's user id. Nothing ran."
122
- )
123
-
124
-
125
- #: What this session decided, for tests and banners: "untouched" | "live" | "repointed:<var>"
126
- #: | "placeholder".
127
- DECISION: str = "untouched"
128
-
129
-
130
- def is_live(user: str, host: str) -> bool:
131
- """Does this connection identity name the live database?"""
132
- ref = user.split(".", 1)[1] if "." in (user or "") else ""
133
- return ref in LIVE_PROJECT_REFS or (host or "").strip().lower() in LIVE_HOSTS
134
-
135
-
136
- def _dotenv_values() -> dict[str, str]:
137
- """The ``.env`` a later ``load_dotenv()`` would read — it never overrides what is set here."""
138
- try:
139
- from dotenv import dotenv_values, find_dotenv
140
- except ImportError: # pragma: no cover — python-dotenv absent: env only
141
- return {}
142
- path = find_dotenv(usecwd=True)
143
- return {k: v for k, v in (dotenv_values(path) if path else {}).items() if v is not None}
144
-
145
-
146
- def _five_from_url(url: str) -> dict[str, str]:
147
- parts = urlsplit(url)
148
- return {
149
- "SUPABASE_MATRIX_HOST": parts.hostname or "",
150
- "SUPABASE_MATRIX_PORT": str(parts.port or 5432),
151
- "SUPABASE_MATRIX_USER": unquote(parts.username or ""),
152
- "SUPABASE_MATRIX_PASSWORD": unquote(parts.password or ""),
153
- "SUPABASE_MATRIX_DATABASE_NAME": (parts.path or "/postgres").lstrip("/") or "postgres",
154
- }
155
-
156
-
157
- def decide(
158
- env: dict[str, str],
159
- dotenv: dict[str, str],
160
- *,
161
- live_flag: bool,
162
- reason: str,
163
- now: datetime,
164
- ) -> tuple[str, dict[str, str] | None, str]:
165
- """``(decision, five variables to set or None, banner)``. Pure — the hook applies it."""
166
- effective = {k: env.get(k) or dotenv.get(k, "") for k in DB_VARS}
167
- if not is_live(effective["SUPABASE_MATRIX_USER"], effective["SUPABASE_MATRIX_HOST"]):
168
- return "untouched", None, ""
169
- if live_flag:
170
- if not reason.strip():
171
- raise pytest.UsageError(
172
- "--live-db needs --live-db-reason \"<why>\": nothing else records why a test run "
173
- "touched the live database."
174
- )
175
- local = now.astimezone(ZoneInfo(WINDOW_TZ))
176
- if not (WINDOW_START <= local.hour < WINDOW_END):
177
- raise pytest.UsageError(
178
- f"--live-db refused: it is {local:%H:%M} Pacific, and the live database is open "
179
- f"to test runs only {WINDOW_START:02d}:00–{WINDOW_END:02d}:00 Pacific."
180
- )
181
- return "live", None, f"── LIVE DATABASE under pytest · reason: {reason.strip()}"
182
- for var in TARGET_URL_VARS:
183
- url = env.get(var) or dotenv.get(var, "")
184
- if url:
185
- five = _five_from_url(url)
186
- if is_live(five["SUPABASE_MATRIX_USER"], five["SUPABASE_MATRIX_HOST"]):
187
- raise pytest.UsageError(f"{var} names the LIVE database; it cannot be a test target.")
188
- return (
189
- f"repointed:{var}",
190
- five,
191
- f"── the live database was configured; this test run uses {var} instead "
192
- "(pass --live-db --live-db-reason inside 1–4 AM Pacific to reach live on purpose).",
193
- )
194
- return (
195
- "placeholder",
196
- dict(PLACEHOLDER),
197
- "── the live database was configured and no test target is set "
198
- "(MATRX_TEST_DATABASE_URL / SUPABASE_BRANCH_DATABASE_URL); database connections in this "
199
- "run go to an unreachable placeholder and FAIL instead of reaching production.",
200
- )
201
-
202
-
203
- def pytest_addoption(parser: pytest.Parser) -> None:
204
- group = parser.getgroup("matrx-live-db", "the live platform database under pytest")
205
- group.addoption("--live-db", action="store_true", default=False,
206
- help="reach the LIVE database on purpose (needs --live-db-reason and 1-4 AM Pacific)")
207
- group.addoption("--live-db-reason", action="store", default="",
208
- help="why this run needs the live database")
209
-
210
-
211
- _APPLIED = False
212
-
213
-
214
- def _apply(live_flag: bool, reason: str) -> None:
215
- """Decide once per process and repoint the five variables. Idempotent."""
216
- global DECISION, _APPLIED
217
- if _APPLIED:
218
- return
219
- refuse_a_real_person(dict(os.environ), _dotenv_values())
220
- decision, five, banner = decide(
221
- dict(os.environ),
222
- _dotenv_values(),
223
- live_flag=live_flag,
224
- reason=reason,
225
- now=datetime.now(ZoneInfo(WINDOW_TZ)),
226
- )
227
- DECISION = decision
228
- _APPLIED = True
229
- if five is not None:
230
- os.environ.update(five)
231
- if banner:
232
- print(banner)
233
- http = decide_http(dict(os.environ), _dotenv_values(), live_flag=live_flag)
234
- if http is not None:
235
- os.environ.update(http)
236
- print(
237
- "── the live Supabase HTTP API was configured; its URL and secret keys point at an "
238
- "unreachable placeholder in this run (pass --live-db --live-db-reason inside 1–4 AM "
239
- "Pacific to reach live on purpose)."
240
- )
241
-
242
-
243
- @pytest.hookimpl(tryfirst=True)
244
- def pytest_load_initial_conftests(early_config: pytest.Config, parser: pytest.Parser, args: list[str]) -> None:
245
- """THE EARLIEST POINT a plugin can act, and the one that matters (2026-09-27).
246
-
247
- pytest imports every command-line path's ``conftest.py`` — and that conftest's
248
- package ``__init__`` — during THIS hook, before ``pytest_configure``. A package
249
- ``__init__`` that imports a module which registers the database pool (aidream's
250
- ``aidream/api/mcp/agent_service/__init__.py`` → server → ``db``) froze the LIVE
251
- identity into the pool for the whole session while the repoint was still waiting in
252
- ``pytest_configure``. The options are already parsed here
253
- (``early_config.known_args_namespace``), so the decision runs before any conftest.
254
- """
255
- ns = early_config.known_args_namespace
256
- _apply(
257
- bool(getattr(ns, "live_db", False)),
258
- str(getattr(ns, "live_db_reason", "") or ""),
259
- )
260
-
261
-
262
- @pytest.hookimpl(tryfirst=True)
263
- def pytest_configure(config: pytest.Config) -> None:
264
- # Normally a no-op: pytest_load_initial_conftests already decided. Kept for runs
265
- # that bypass initial-conftest loading (pytest.main with plugins=, --noconftest).
266
- _apply(
267
- bool(config.getoption("--live-db", default=False)),
268
- str(config.getoption("--live-db-reason", default="") or ""),
269
- )
270
-
271
-
272
- __all__ = ["decide_http", "is_live_url", "DECISION", "TEST_ACCOUNT_IDS", "refuse_a_real_person", "LIVE_HOSTS", "LIVE_PROJECT_REFS", "decide", "is_live"]