matrx-orm 3.1.148__tar.gz → 3.1.150__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 (382) hide show
  1. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/PKG-INFO +2 -2
  2. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/__init__.py +2 -0
  3. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/items.py +66 -1
  4. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/README.md +9 -0
  5. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/fallback.py +33 -14
  6. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/pyproject.toml +2 -2
  7. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_record_error_bounded_insert.py +66 -0
  8. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_secrets_battery.py +93 -0
  9. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/.gitignore +0 -0
  10. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/AGENTS.md +0 -0
  11. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/BASE_CLASS_METHODS.md +0 -0
  12. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/CLAUDE.md +0 -0
  13. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/MODEL_API.md +0 -0
  14. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/README.md +0 -0
  15. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/database/orm/extended/managers/ai_model_base.py +0 -0
  16. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/docs/migrations.md +0 -0
  17. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/FEATURE.md +0 -0
  18. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/MODULE_README.md +0 -0
  19. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/__init__.py +0 -0
  20. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/adapters/MODULE_README.md +0 -0
  21. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/adapters/__init__.py +0 -0
  22. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/adapters/async_postgresql.py +0 -0
  23. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/adapters/base_adapter.py +0 -0
  24. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/adapters/postgresql.py +0 -0
  25. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/adapters/postgrest_client_adapter.py +0 -0
  26. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/adapters/supabase_adapter.py +0 -0
  27. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/admin/FEATURE.md +0 -0
  28. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/admin/__init__.py +0 -0
  29. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/admin/router.py +0 -0
  30. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/api/__init__.py +0 -0
  31. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/api/auth.py +0 -0
  32. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/api/config.py +0 -0
  33. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/api/handlers.py +0 -0
  34. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/api/protocol.py +0 -0
  35. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/api/server.py +0 -0
  36. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/associations.py +0 -0
  37. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/cache_debug.py +0 -0
  38. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/catalog.py +0 -0
  39. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/catalog_sql.py +0 -0
  40. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/client/MODULE_README.md +0 -0
  41. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/client/__init__.py +0 -0
  42. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/client/postgres_connection.py +0 -0
  43. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/client/postgrest.py +0 -0
  44. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/client/supabase_auth.py +0 -0
  45. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/client/supabase_config.py +0 -0
  46. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/client/supabase_manager.py +0 -0
  47. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/EXTENDED-TASK.md +0 -0
  48. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/FEATURE.md +0 -0
  49. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/MODULE_README.md +0 -0
  50. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/RELATIONS-TASKS.md +0 -0
  51. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/TASKS.md +0 -0
  52. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/__init__.py +0 -0
  53. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/async_db_manager.py +0 -0
  54. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/base.py +0 -0
  55. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/config.py +0 -0
  56. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/connections.py +0 -0
  57. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/db_function.py +0 -0
  58. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/diagnostics.py +0 -0
  59. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/expressions.py +0 -0
  60. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/extended.py +0 -0
  61. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/fields.py +0 -0
  62. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/introspection.py +0 -0
  63. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/listen.py +0 -0
  64. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/loop_filters.py +0 -0
  65. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/model_dto.py +0 -0
  66. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/model_view.py +0 -0
  67. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/one_database.py +0 -0
  68. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/paginator.py +0 -0
  69. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/pool_maintenance.py +0 -0
  70. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/pool_watch.py +0 -0
  71. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/pooler_role.py +0 -0
  72. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/pydantic_bridge.py +0 -0
  73. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/registry.py +0 -0
  74. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/relations.py +0 -0
  75. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/resilience.py +0 -0
  76. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/rls_session.py +0 -0
  77. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/session_context.py +0 -0
  78. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/signals.py +0 -0
  79. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/tls.py +0 -0
  80. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/transaction.py +0 -0
  81. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/types.py +0 -0
  82. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/write_queue.py +0 -0
  83. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/core/write_retry.py +0 -0
  84. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/entity.py +0 -0
  85. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/error_handling.py +0 -0
  86. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/exceptions.py +0 -0
  87. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/extended/__init__.py +0 -0
  88. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/extended/app_error_handler.py +0 -0
  89. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/identity_rule.py +0 -0
  90. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/local_sqlite.py +0 -0
  91. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/middleware/__init__.py +0 -0
  92. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/middleware/base.py +0 -0
  93. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/MODULE_README.md +0 -0
  94. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/__init__.py +0 -0
  95. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/cli.py +0 -0
  96. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/ddl.py +0 -0
  97. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/diff.py +0 -0
  98. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/executor.py +0 -0
  99. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/integration.py +0 -0
  100. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/loader.py +0 -0
  101. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/operations.py +0 -0
  102. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/state.py +0 -0
  103. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/migrations/table_filter.py +0 -0
  104. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/no_org_assignment.py +0 -0
  105. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/FEATURE.md +0 -0
  106. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/MODULE_README.md +0 -0
  107. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/__init__.py +0 -0
  108. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/bulk_update_values.py +0 -0
  109. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/catalog_select.py +0 -0
  110. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/conflict.py +0 -0
  111. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/conflict_writes.py +0 -0
  112. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/create.py +0 -0
  113. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/db_functions.py +0 -0
  114. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/delete.py +0 -0
  115. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/dynamic_admin.py +0 -0
  116. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/dynamic_crud.py +0 -0
  117. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/graph_walk.py +0 -0
  118. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/latest_rows.py +0 -0
  119. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/queue_claim.py +0 -0
  120. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/read.py +0 -0
  121. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/relational_backfill.py +0 -0
  122. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/staging_load.py +0 -0
  123. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/operations/update.py +0 -0
  124. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/platform_access.py +0 -0
  125. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/platform_db.py +0 -0
  126. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/py.typed +0 -0
  127. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/pytest_plugin.py +0 -0
  128. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/python_sql/MODULE_README.md +0 -0
  129. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/python_sql/__init__.py +0 -0
  130. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/python_sql/db_objects.py +0 -0
  131. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/python_sql/table_detailed_relationships.py +0 -0
  132. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/python_sql/table_typescript_relationship.py +0 -0
  133. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/query/FEATURE.md +0 -0
  134. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/query/MODULE_README.md +0 -0
  135. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/query/__init__.py +0 -0
  136. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/query/builder.py +0 -0
  137. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/query/executor.py +0 -0
  138. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/resources/__init__.py +0 -0
  139. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/resources/additional-assigners-2026-09-12.json +0 -0
  140. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/resources/org_assignment_trigger_baseline.json +0 -0
  141. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/FEATURE.md +0 -0
  142. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/MODULE_README.md +0 -0
  143. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/__init__.py +0 -0
  144. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/code_handler.py +0 -0
  145. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/codegen_writer.py +0 -0
  146. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/columns.py +0 -0
  147. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/common.py +0 -0
  148. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/diff_preview.py +0 -0
  149. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/entity_capabilities.py +0 -0
  150. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/generator.py +0 -0
  151. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/helpers/__init__.py +0 -0
  152. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/helpers/base_generators.py +0 -0
  153. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/helpers/entity_generators.py +0 -0
  154. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/helpers/git_checker.py +0 -0
  155. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/package_wiring.py +0 -0
  156. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/relationships.py +0 -0
  157. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/runner.py +0 -0
  158. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/schema.py +0 -0
  159. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/schema_manager.py +0 -0
  160. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/tables.py +0 -0
  161. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/schema_builder/views.py +0 -0
  162. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/FEATURE.md +0 -0
  163. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/attachments.py +0 -0
  164. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/crypto.py +0 -0
  165. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/host_authorization.py +0 -0
  166. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/model.py +0 -0
  167. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/mutation_receipts.py +0 -0
  168. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/org_service.py +0 -0
  169. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/secrets_battery/service.py +0 -0
  170. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/__init__.py +0 -0
  171. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/coalesce.py +0 -0
  172. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/dag.py +0 -0
  173. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/errors.py +0 -0
  174. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/flush.py +0 -0
  175. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/lifecycle.py +0 -0
  176. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/managed.py +0 -0
  177. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/op.py +0 -0
  178. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/reads.py +0 -0
  179. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/session.py +0 -0
  180. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/session/telemetry.py +0 -0
  181. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/sql_executor/MODULE_README.md +0 -0
  182. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/sql_executor/__init__.py +0 -0
  183. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/sql_executor/executor.py +0 -0
  184. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/sql_executor/queries.py +0 -0
  185. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/sql_executor/registry.py +0 -0
  186. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/sql_executor/types.py +0 -0
  187. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/sql_executor/utils.py +0 -0
  188. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/state.py +0 -0
  189. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/utils/__init__.py +0 -0
  190. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/utils/sql_utils.py +0 -0
  191. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/matrx_orm/utils/type_converters.py +0 -0
  192. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/scripts/git-branches.sh +0 -0
  193. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/scripts/publish.sh +0 -0
  194. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/scripts/release.sh +0 -0
  195. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/MODULE_README.md +0 -0
  196. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/__init__.py +0 -0
  197. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/conftest.py +0 -0
  198. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/MODULE_README.md +0 -0
  199. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/__init__.py +0 -0
  200. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_adapter_registry.py +0 -0
  201. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_admin_db_columns.py +0 -0
  202. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_admin_response_rendering.py +0 -0
  203. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_admin_search_negation.py +0 -0
  204. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_admin_search_sentinels.py +0 -0
  205. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_advisory_lock.py +0 -0
  206. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_agent_message.py +0 -0
  207. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_api_auth.py +0 -0
  208. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_api_config.py +0 -0
  209. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_api_handlers.py +0 -0
  210. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_api_protocol.py +0 -0
  211. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_array_agg_order_by.py +0 -0
  212. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_associations.py +0 -0
  213. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_associations_wiring.py +0 -0
  214. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_bulk_hydration_offload.py +0 -0
  215. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_bulk_update_by_pk.py +0 -0
  216. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_bulk_upsert_increment_set_fields.py +0 -0
  217. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_cache_debug.py +0 -0
  218. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_call_function.py +0 -0
  219. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_case_when.py +0 -0
  220. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_catalog.py +0 -0
  221. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_committed_row_guard.py +0 -0
  222. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_composite_pk_filter.py +0 -0
  223. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_composite_pk_write_paths.py +0 -0
  224. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_config.py +0 -0
  225. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_conflict_target.py +0 -0
  226. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_conflict_writes.py +0 -0
  227. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_connection_codecs.py +0 -0
  228. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_connection_poison_guard.py +0 -0
  229. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_connection_primitives.py +0 -0
  230. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_count_composite_distinct.py +0 -0
  231. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_count_limit_param_leak.py +0 -0
  232. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_db_function_field.py +0 -0
  233. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_ddl_generator.py +0 -0
  234. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_deadlock_retry.py +0 -0
  235. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_derived_table.py +0 -0
  236. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_dirty_tracking.py +0 -0
  237. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_dynamic_crud.py +0 -0
  238. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_exceptions.py +0 -0
  239. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_execute_query_integrity_mapping.py +0 -0
  240. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_expression_primitives.py +0 -0
  241. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_fields.py +0 -0
  242. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_filter_jsonb_agg_array_index.py +0 -0
  243. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_from_alias.py +0 -0
  244. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_fts.py +0 -0
  245. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_func_expression_args.py +0 -0
  246. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_graph_walk.py +0 -0
  247. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_having_annotate_alias.py +0 -0
  248. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_insert_ignore_and_admin_primitives.py +0 -0
  249. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_introspect_rls_policies.py +0 -0
  250. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_join_and_aggregate.py +0 -0
  251. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_latest_rows.py +0 -0
  252. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_listen_notify.py +0 -0
  253. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_local_sqlite.py +0 -0
  254. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_lock_contention_retry.py +0 -0
  255. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_managed_write_guard.py +0 -0
  256. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_matrx_entity.py +0 -0
  257. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_migration_diff_types.py +0 -0
  258. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_migration_loader.py +0 -0
  259. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_model_instance.py +0 -0
  260. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_model_meta.py +0 -0
  261. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_optimistic_concurrency.py +0 -0
  262. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_order_by_expression.py +0 -0
  263. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_org_assignment_inventory.py +0 -0
  264. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_parameter_name_hydration.py +0 -0
  265. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_patch_jsonb_path.py +0 -0
  266. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_persisted_count.py +0 -0
  267. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_pool_holder_census.py +0 -0
  268. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_pool_loop_recreation.py +0 -0
  269. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_pool_maintenance.py +0 -0
  270. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_postgrest_filters.py +0 -0
  271. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_pydantic_bridge.py +0 -0
  272. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_query_builder.py +0 -0
  273. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_query_error_detail.py +0 -0
  274. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_query_executor_sql.py +0 -0
  275. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_query_timeout.py +0 -0
  276. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_querybuilder_clone_semantics.py +0 -0
  277. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_queue_claim.py +0 -0
  278. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_read_connection_retry.py +0 -0
  279. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_registry.py +0 -0
  280. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_registry_multi_database.py +0 -0
  281. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_registry_multi_schema.py +0 -0
  282. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_relational_backfill.py +0 -0
  283. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_relations.py +0 -0
  284. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_resilience.py +0 -0
  285. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_rls_session_scope.py +0 -0
  286. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_schema_exists.py +0 -0
  287. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_session_advisory_lock.py +0 -0
  288. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_standalone_write_session_context.py +0 -0
  289. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_state_cache.py +0 -0
  290. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_subquery_filter_raw.py +0 -0
  291. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_subquery_in_filter.py +0 -0
  292. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_subquery_nested_expressions.py +0 -0
  293. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_supabase_auth.py +0 -0
  294. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_supabase_config.py +0 -0
  295. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_tls.py +0 -0
  296. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_transaction_database_identity.py +0 -0
  297. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_typed_join_projection.py +0 -0
  298. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_typed_predicates.py +0 -0
  299. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_update_case_expression.py +0 -0
  300. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_update_subquery.py +0 -0
  301. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_update_with_rebase.py +0 -0
  302. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_upsert_default_leak.py +0 -0
  303. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_upsert_with_conflict.py +0 -0
  304. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_values_jsonb_decode.py +0 -0
  305. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_watched_lifecycle.py +0 -0
  306. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_write_queue_deadline.py +0 -0
  307. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level1/test_write_retry_semantics.py +0 -0
  308. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/MODULE_README.md +0 -0
  309. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/__init__.py +0 -0
  310. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/conftest.py +0 -0
  311. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_bulk_ops.py +0 -0
  312. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_cache_integration.py +0 -0
  313. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_crud.py +0 -0
  314. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_foreign_keys.py +0 -0
  315. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_m2m.py +0 -0
  316. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_manager.py +0 -0
  317. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_migrations_live.py +0 -0
  318. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_query_execution.py +0 -0
  319. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/test_schema_diff.py +0 -0
  320. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/level2/verify_committed_row_guard_pg17.py +0 -0
  321. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/live_pooler_role.py +0 -0
  322. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project/.env.example +0 -0
  323. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project/README.md +0 -0
  324. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project/__init__.py +0 -0
  325. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project/generate.py +0 -0
  326. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project/generated/.gitkeep +0 -0
  327. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project/matrx_orm.yaml +0 -0
  328. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project/test_schema_generation.py +0 -0
  329. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project_desktop/.env.example +0 -0
  330. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project_desktop/README.md +0 -0
  331. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project_desktop/__init__.py +0 -0
  332. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project_desktop/client_example.py +0 -0
  333. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project_desktop/client_example.ts +0 -0
  334. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project_desktop/client_supabase_example.py +0 -0
  335. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/sample_project_desktop/server.py +0 -0
  336. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/entity_tests.py +0 -0
  337. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_base_generation.py +0 -0
  338. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_composite_pk_fk_generation.py +0 -0
  339. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_composite_unique_generation.py +0 -0
  340. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_dto_identity_generation.py +0 -0
  341. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_entity_capability_generation.py +0 -0
  342. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_enum_ordering.py +0 -0
  343. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_generate_schema.py +0 -0
  344. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_junction_analysis.py +0 -0
  345. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_multi_schema_output.py +0 -0
  346. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_schema_analysis.py +0 -0
  347. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_sql_expression_defaults.py +0 -0
  348. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_table_relationships_query.py +0 -0
  349. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema/test_view_generation.py +0 -0
  350. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema_builder/test_array_default_parsing.py +0 -0
  351. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema_builder/test_focused_generation_plan.py +0 -0
  352. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/schema_builder/test_host_models_aggregator.py +0 -0
  353. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/__init__.py +0 -0
  354. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/conftest.py +0 -0
  355. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_cache_no_downgrade.py +0 -0
  356. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_capture_poison_proof.py +0 -0
  357. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_coalesce.py +0 -0
  358. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_dag.py +0 -0
  359. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_disk_spill_fallback.py +0 -0
  360. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_flush_individual_fallback.py +0 -0
  361. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_governed_write.py +0 -0
  362. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_managed.py +0 -0
  363. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_op_enqueue_site.py +0 -0
  364. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_reads.py +0 -0
  365. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_record_error_storm.py +0 -0
  366. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_session.py +0 -0
  367. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/session/test_spill_guard_plugin.py +0 -0
  368. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_array_arg_element_type.py +0 -0
  369. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_database_name_alias.py +0 -0
  370. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_db_functions.py +0 -0
  371. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_dynamic_select_unregistered.py +0 -0
  372. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_immutable_insert_or_exact_verify.py +0 -0
  373. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_keyed_digest.py +0 -0
  374. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_model_cls_refactor.py +0 -0
  375. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_no_blocking_asyncpg_tls.py +0 -0
  376. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_one_database.py +0 -0
  377. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_order_by_desc_nulls_last.py +0 -0
  378. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_pooler_role_guard.py +0 -0
  379. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_secrets_minting_keys.py +0 -0
  380. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_sql_param_casts.py +0 -0
  381. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_sync_twins_guard.py +0 -0
  382. {matrx_orm-3.1.148 → matrx_orm-3.1.150}/tests/test_user_visible_lookup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: matrx-orm
3
- Version: 3.1.148
3
+ Version: 3.1.150
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
@@ -25,7 +25,7 @@ Requires-Python: >=3.13
25
25
  Requires-Dist: asyncpg>=0.31.0
26
26
  Requires-Dist: cryptography>=43.0
27
27
  Requires-Dist: gitpython>=3.1.40
28
- Requires-Dist: matrx-utils>=2.0.40
28
+ Requires-Dist: matrx-utils>=2.0.41
29
29
  Requires-Dist: psycopg-pool>=3.2.5
30
30
  Requires-Dist: psycopg[binary]>=3.2.5
31
31
  Requires-Dist: python-dotenv>=1.0
@@ -80,6 +80,7 @@ from .items import (
80
80
  FieldSpec,
81
81
  ItemGrantSpec,
82
82
  SandboxInjectionWithoutEnvKeyError,
83
+ SealedBrowserFillPasswordError,
83
84
  SealedFieldError,
84
85
  TransferResult,
85
86
  add_credential_field,
@@ -215,6 +216,7 @@ __all__ = [
215
216
  "FieldSpec",
216
217
  "ItemGrantSpec",
217
218
  "SandboxInjectionWithoutEnvKeyError",
219
+ "SealedBrowserFillPasswordError",
218
220
  "SealedFieldError",
219
221
  "URI_MATCH_MODES",
220
222
  "add_credential_field",
@@ -110,6 +110,21 @@ class SandboxInjectionWithoutEnvKeyError(ValueError):
110
110
  together) or leave injection off."""
111
111
 
112
112
 
113
+ class SealedBrowserFillPasswordError(ValueError):
114
+ """A ``password`` field is (or would become) ``handling='sealed'`` on an
115
+ item with ``browser_fill_enabled=true``. A sealed value has NO reveal
116
+ path anywhere — including the browser-fill boundary itself
117
+ (``vault.py`` ``_prepare_fill_payload`` / ``vault_resolve_for_browser``
118
+ both refuse a sealed field with "is sealed and cannot be filled into a
119
+ page"), so a browser-fill login built this way can never actually fill
120
+ a page: it looks saved but is permanently unusable.
121
+
122
+ Refused LOUDLY at every write path instead of accepted-and-broken —
123
+ 'revealable' is the canonical handling for a browser-fill password: it
124
+ still requires reveal capability + recent auth to resolve, but (unlike
125
+ 'sealed') it is allowed to cross the browser-fill boundary at all."""
126
+
127
+
113
128
  class ProtectedSecretPurposeError(PermissionError):
114
129
  """A generic path reached a native-provider-only secret before decrypt."""
115
130
 
@@ -255,6 +270,24 @@ def _validate_sandbox_injectable(
255
270
  )
256
271
 
257
272
 
273
+ def _refuse_sealed_browser_fill_password(
274
+ *, browser_fill_enabled: bool, field_key: str, handling: str
275
+ ) -> None:
276
+ """Catch the sealed/browser-fill contradiction at the write boundary —
277
+ see :class:`SealedBrowserFillPasswordError`. Scoped to the ``password``
278
+ field key: that is the one the browser-fill path actually needs, and
279
+ the one the live incident hit (a ``website_login`` created with a
280
+ sealed password was silently unusable)."""
281
+ if browser_fill_enabled and field_key == "password" and handling == "sealed":
282
+ raise SealedBrowserFillPasswordError(
283
+ "field 'password' cannot be handling='sealed' on an item with "
284
+ "browser_fill_enabled=true — a sealed value is refused at fill "
285
+ "time, so this login would be saved but could never actually "
286
+ "fill a page. Use handling='revealable' for a browser-fill "
287
+ "login instead."
288
+ )
289
+
290
+
258
291
  def _validate_uri_match_mode(mode: str) -> None:
259
292
  if mode not in URI_MATCH_MODES:
260
293
  raise ValueError(f"uri_match_mode must be one of {URI_MATCH_MODES}; got {mode!r}")
@@ -588,6 +621,11 @@ async def create_credential_bundle(
588
621
  env_key=spec.env_key,
589
622
  inject_into_sandbox=spec.inject_into_sandbox,
590
623
  )
624
+ _refuse_sealed_browser_fill_password(
625
+ browser_fill_enabled=bool(browser_fill_enabled),
626
+ field_key=spec.field_key,
627
+ handling=spec.handling,
628
+ )
591
629
  if not isinstance(spec.value, str):
592
630
  raise ValueError(f"field {spec.field_key!r}: value must be a string")
593
631
  if spec.field_key in seen:
@@ -709,6 +747,21 @@ async def update_credential_item(
709
747
  touches ciphertext."""
710
748
  if status is not None and status not in ITEM_STATUSES:
711
749
  raise ValueError(f"status must be one of {ITEM_STATUSES}; got {status!r}")
750
+ if browser_fill_enabled:
751
+ sealed_password = await UserSecret.filter(
752
+ credential_item_id=item_id,
753
+ field_key="password",
754
+ handling="sealed",
755
+ is_active=True,
756
+ deleted_at__isnull=True,
757
+ ).values("id")
758
+ if sealed_password:
759
+ raise SealedBrowserFillPasswordError(
760
+ "cannot set browser_fill_enabled=true — this item's 'password' field is "
761
+ "handling='sealed', which is refused at fill time, so the login would be "
762
+ "saved but could never actually fill a page. Rotate/replace the password "
763
+ "field with handling='revealable' first."
764
+ )
712
765
  updates: dict[str, Any] = {"updated_by": actor_id, "updated_at": datetime.now(UTC)}
713
766
  if display_name is not None:
714
767
  updates["display_name"] = display_name
@@ -827,6 +880,11 @@ async def add_credential_field(
827
880
  raise ValueError("value must be a string")
828
881
  async with transaction(PACKAGE_DB_NAME):
829
882
  raw = await _lock_item_raw(item_id)
883
+ _refuse_sealed_browser_fill_password(
884
+ browser_fill_enabled=bool(raw.get("browser_fill_enabled")),
885
+ field_key=spec.field_key,
886
+ handling=spec.handling,
887
+ )
830
888
  instance = await UserSecret.create(
831
889
  user_id=raw.get("user_id"),
832
890
  organization_id=raw.get("organization_id"),
@@ -999,8 +1057,9 @@ async def update_field_metadata(
999
1057
  rows = await UserSecret.filter(id=field_id, deleted_at__isnull=True).values("credential_item_id")
1000
1058
  if not rows:
1001
1059
  raise SecretNotFoundError(f"credential field {field_id} not found")
1060
+ item_raw: dict[str, Any] | None = None
1002
1061
  if rows[0].get("credential_item_id"):
1003
- await _lock_item_raw(str(rows[0]["credential_item_id"]))
1062
+ item_raw = await _lock_item_raw(str(rows[0]["credential_item_id"]))
1004
1063
  rows = await UserSecret.filter(id=field_id, deleted_at__isnull=True).select_for_update().values(
1005
1064
  *_FIELD_FIELDS, "user_id", "organization_id"
1006
1065
  )
@@ -1014,6 +1073,12 @@ async def update_field_metadata(
1014
1073
  f"field {raw.get('field_key') or raw.get('key')!r} is sealed — sealing is "
1015
1074
  "a one-way door; rotate/replace the field instead of unsealing it"
1016
1075
  )
1076
+ if handling is not None:
1077
+ _refuse_sealed_browser_fill_password(
1078
+ browser_fill_enabled=bool((item_raw or {}).get("browser_fill_enabled")),
1079
+ field_key=str(raw.get("field_key") or ""),
1080
+ handling=handling,
1081
+ )
1017
1082
 
1018
1083
  # The POST-patch state is what matters: enabling injection on a keyless
1019
1084
  # field AND clearing the alias of an already-injecting field are the
@@ -273,6 +273,15 @@ printed (`storm: … suppressed …`), and folded into the next admitted row as
273
273
  `context._storm.suppressed_in_previous_window`. Nothing is lost, nothing floods.
274
274
  Guard: `tests/session/test_record_error_storm.py`.
275
275
 
276
+ If the bounded `ops.system_error` insert itself times out or meets a lock, the
277
+ fallback emits exactly one `matrx_orm_system_error_capture_failed` ERROR event.
278
+ Its `matrx_system_error` metadata keeps the original kind/error, request and route,
279
+ plus a bounded, secret-redacted original traceback, the capture exception and operation.
280
+ It never copies the failed capture's payload or context into that app-log event. Do not
281
+ add a `vcprint` banner beside that event: `vcprint` is also captured by the app-log
282
+ handler and would turn one failed capture into two unrelated error families. Guard:
283
+ `tests/session/test_record_error_bounded_insert.py`.
284
+
276
285
  ## Telemetry (optional)
277
286
 
278
287
  If OpenTelemetry is installed, Session emits spans and metrics:
@@ -28,6 +28,7 @@ from typing import Any
28
28
  from uuid import UUID
29
29
 
30
30
  from matrx_utils import vcprint
31
+ from matrx_utils.secret_detection import redact_secrets
31
32
 
32
33
  from matrx_orm.exceptions import describe_db_exception
33
34
  from matrx_orm.session.op import SessionOp
@@ -70,6 +71,11 @@ STORM_ROW_BUDGET = 3
70
71
  CAPTURE_ACQUIRE_TIMEOUT_SECONDS = 2.0
71
72
  CAPTURE_LOCK_TIMEOUT_MS = 1500
72
73
  CAPTURE_STATEMENT_TIMEOUT_MS = 2500
74
+ # A failed error capture cannot make the forensic diagnostic itself an
75
+ # unbounded durable log payload. This bound is deliberately below app_log's
76
+ # generic message cap because this is a last-resort, high-frequency path.
77
+ CAPTURE_FAILURE_DIAGNOSTIC_MAX = 8_192
78
+ CAPTURE_FAILURE_DIAGNOSTIC_TRUNCATION_MARKER = "… [truncated]"
73
79
  _storm_state: dict[tuple[str, str, str], dict[str, Any]] = {}
74
80
 
75
81
 
@@ -147,6 +153,17 @@ def _serialize_primary_key(pk_field: str, pk_value: str) -> str:
147
153
  return json.dumps({pk_field: pk_value})
148
154
 
149
155
 
156
+ def _capture_failure_diagnostic(value: object) -> str:
157
+ """Redact and bound text retained when ``system_error`` capture fails."""
158
+ redacted, _ = redact_secrets(str(value))
159
+ if len(redacted) <= CAPTURE_FAILURE_DIAGNOSTIC_MAX:
160
+ return redacted
161
+ prefix_length = CAPTURE_FAILURE_DIAGNOSTIC_MAX - len(
162
+ CAPTURE_FAILURE_DIAGNOSTIC_TRUNCATION_MARKER
163
+ )
164
+ return redacted[:prefix_length] + CAPTURE_FAILURE_DIAGNOSTIC_TRUNCATION_MARKER
165
+
166
+
150
167
  def _safe_uuid(value: Any) -> str | None:
151
168
  """Return ``value`` only if it is a valid UUID, else ``None``.
152
169
 
@@ -724,27 +741,29 @@ async def record_error(
724
741
  color="yellow",
725
742
  )
726
743
  except Exception as capture_exc:
727
- # Last resort — the capture itself failed. Don't let it crash the
728
- # caller (we're usually already on an error/cancel path). Scream.
729
- vcprint(
730
- "\n"
731
- "╔══════════════════════════════════════════════════════════════════╗\n"
732
- "║ matrx-orm — system_error capture FAILED ║\n"
733
- "╚══════════════════════════════════════════════════════════════════╝\n"
734
- f" kind: {kind}\n"
735
- f" error: {resolved_error_text}\n"
736
- f" capture exc: {type(capture_exc).__name__}: {capture_exc}\n"
737
- f" traceback:\n{tb_text}",
738
- color="red",
739
- )
744
+ # ``vcprint(..., color="red")`` is itself a logger call. Emitting it
745
+ # beside this structured event made ONE failed capture appear as TWO
746
+ # unrelated ERROR families in ``app_log``. Keep one ERROR so the
747
+ # durable log has an exact, queryable incident without concealing the
748
+ # original failure or the bounded-capture refusal.
740
749
  logger.error(
741
750
  "matrx_orm_system_error_capture_failed",
742
751
  extra={
743
752
  "matrx_system_error": {
744
753
  "kind": kind,
745
- "error_text": resolved_error_text,
754
+ "error_type": resolved_error_type,
755
+ "error_text": _capture_failure_diagnostic(resolved_error_text),
746
756
  "request_id": request_id,
747
757
  "user_id": user_id,
758
+ "route": route,
759
+ "capture_exception_type": type(capture_exc).__name__,
760
+ "capture_exception_text": _capture_failure_diagnostic(capture_exc),
761
+ "capture_operation": "ops.system_error.insert",
762
+ # Do not include the original payload or context here: either
763
+ # can contain request secrets. This traceback is the bounded,
764
+ # redacted diagnostic that lets the one surviving app-log event
765
+ # retain the original failure boundary instead.
766
+ "original_traceback": _capture_failure_diagnostic(tb_text),
748
767
  }
749
768
  },
750
769
  )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "matrx-orm"
3
- version = "3.1.148"
3
+ version = "3.1.150"
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" }
@@ -41,7 +41,7 @@ dependencies = [
41
41
  "gitpython>=3.1.40",
42
42
  "psycopg[binary]>=3.2.5",
43
43
  "psycopg-pool>=3.2.5",
44
- "matrx-utils>=2.0.40",
44
+ "matrx-utils>=2.0.41",
45
45
  "pyyaml>=6.0.3",
46
46
  "python-dotenv>=1.0",
47
47
  "cryptography>=43.0",
@@ -14,6 +14,8 @@ set AFTER the INSERT (too late to protect anything).
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ import logging
18
+
17
19
  import pytest
18
20
 
19
21
  from matrx_orm.session import fallback
@@ -87,3 +89,67 @@ async def test_capture_insert_is_bounded_before_it_touches_the_table(monkeypatch
87
89
  assert log[1] == f"SET LOCAL statement_timeout = '{fallback.CAPTURE_STATEMENT_TIMEOUT_MS}ms'"
88
90
  assert log[2].startswith("INSERT INTO ops.system_error")
89
91
  assert len(log) == 3
92
+
93
+
94
+ @pytest.mark.asyncio
95
+ async def test_failed_capture_emits_one_structured_error_not_a_banner_twin(
96
+ monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture
97
+ ) -> None:
98
+ """One failed insert must remain one durable app-log incident."""
99
+
100
+ capture_secret = "sk-" + "a" * 32
101
+ traceback_sentinel = "TRACEBACK_SENTINEL"
102
+
103
+ async def _failed_insert(**_kwargs) -> None:
104
+ raise RuntimeError(f"lock timeout API_TOKEN={capture_secret}")
105
+
106
+ def _unexpected_banner(*_args, **_kwargs) -> None:
107
+ raise AssertionError("capture failure must not make a second vcprint log event")
108
+
109
+ monkeypatch.setattr(fallback, "_insert_error", _failed_insert)
110
+ monkeypatch.setattr(fallback, "vcprint", _unexpected_banner)
111
+
112
+ with caplog.at_level(logging.ERROR, logger="matrx_orm.session.fallback"):
113
+ await fallback.record_error(
114
+ ValueError("shed"),
115
+ kind="cloud_file_change_feed_shed",
116
+ request_id="request-1",
117
+ user_id="user-1",
118
+ route="/api/cloud-files/changes",
119
+ traceback_text=f"{traceback_sentinel}\nAPI_TOKEN={capture_secret}",
120
+ payload={"access_token": capture_secret},
121
+ context={"credential": capture_secret},
122
+ )
123
+
124
+ records = [
125
+ record
126
+ for record in caplog.records
127
+ if record.name == "matrx_orm.session.fallback"
128
+ and record.getMessage() == "matrx_orm_system_error_capture_failed"
129
+ ]
130
+ assert len(records) == 1
131
+ captured = records[0].matrx_system_error
132
+ assert captured == {
133
+ "kind": "cloud_file_change_feed_shed",
134
+ "error_type": "ValueError",
135
+ "error_text": "ValueError: shed",
136
+ "request_id": "request-1",
137
+ "user_id": "user-1",
138
+ "route": "/api/cloud-files/changes",
139
+ "capture_exception_type": "RuntimeError",
140
+ "capture_exception_text": "lock timeout API_TOKEN=<redacted:token>",
141
+ "capture_operation": "ops.system_error.insert",
142
+ "original_traceback": f"{traceback_sentinel}\nAPI_TOKEN=<redacted:API_TOKEN>",
143
+ }
144
+ assert capture_secret not in repr(captured)
145
+
146
+
147
+ def test_capture_failure_diagnostic_is_bounded_and_secret_safe() -> None:
148
+ secret = "sk-" + "b" * 32
149
+ diagnostic = fallback._capture_failure_diagnostic(
150
+ f"API_TOKEN={secret}\n" + "x" * (fallback.CAPTURE_FAILURE_DIAGNOSTIC_MAX + 1)
151
+ )
152
+
153
+ assert secret not in diagnostic
154
+ assert diagnostic.endswith("… [truncated]")
155
+ assert len(diagnostic) <= fallback.CAPTURE_FAILURE_DIAGNOSTIC_MAX
@@ -923,3 +923,96 @@ def test_error_taxonomy():
923
923
  assert issubclass(SealedFieldError, PermissionError)
924
924
  assert issubclass(FieldNotEditableError, PermissionError)
925
925
  assert issubclass(CredentialItemNotFoundError, LookupError)
926
+
927
+
928
+ # ── Sealed password on a browser-fill item (live incident: a website_login
929
+ # created with handling='sealed' was accepted, then unusable — vault.py's
930
+ # browser-fill path refuses any sealed field at fill time) ─────────────────
931
+
932
+
933
+ def test_refuse_sealed_browser_fill_password_helper():
934
+ """Direct coverage of the boundary check: only the exact combination
935
+ (browser_fill_enabled AND field_key == 'password' AND handling ==
936
+ 'sealed') is refused — every other combination is fine."""
937
+ from matrx_orm.secrets_battery.items import (
938
+ SealedBrowserFillPasswordError,
939
+ _refuse_sealed_browser_fill_password,
940
+ )
941
+
942
+ with pytest.raises(SealedBrowserFillPasswordError, match="cannot be handling='sealed'"):
943
+ _refuse_sealed_browser_fill_password(
944
+ browser_fill_enabled=True, field_key="password", handling="sealed"
945
+ )
946
+
947
+ # A sealed field that is not 'password' does not collide with browser fill.
948
+ _refuse_sealed_browser_fill_password(
949
+ browser_fill_enabled=True, field_key="totp_seed", handling="sealed"
950
+ )
951
+ # A sealed password is fine when the item never fills into a browser.
952
+ _refuse_sealed_browser_fill_password(
953
+ browser_fill_enabled=False, field_key="password", handling="sealed"
954
+ )
955
+ # 'revealable' is exactly the handling the browser-fill path accepts.
956
+ _refuse_sealed_browser_fill_password(
957
+ browser_fill_enabled=True, field_key="password", handling="revealable"
958
+ )
959
+
960
+
961
+ def test_create_credential_bundle_refuses_sealed_password_with_browser_fill_enabled():
962
+ """RED before the fix: a website_login created with browser_fill_enabled
963
+ plus a sealed password field used to be accepted silently and was then
964
+ permanently unfillable (vault.py ~1741 'is sealed and cannot be filled
965
+ into a page'). All field validation in create_credential_bundle runs
966
+ BEFORE the DB transaction opens, so this raises with no DB configured —
967
+ proof the refusal happens at the write boundary, not deep in a query."""
968
+ import asyncio
969
+
970
+ from matrx_orm.secrets_battery import FieldSpec
971
+ from matrx_orm.secrets_battery.items import (
972
+ SealedBrowserFillPasswordError,
973
+ create_credential_bundle,
974
+ )
975
+
976
+ with pytest.raises(SealedBrowserFillPasswordError, match="password.*browser_fill_enabled"):
977
+ asyncio.run(
978
+ create_credential_bundle(
979
+ user_id="u1",
980
+ display_name="AI Matrx",
981
+ browser_fill_enabled=True,
982
+ login_urls=["https://www.aimatrx.com/login"],
983
+ fields=[
984
+ FieldSpec("username", "me@example.com"),
985
+ FieldSpec("password", "hunter2", handling="sealed"),
986
+ ],
987
+ )
988
+ )
989
+
990
+
991
+ def test_create_credential_bundle_validation_accepts_revealable_password():
992
+ """The canonical fix: 'revealable' clears the same validation loop and
993
+ the function proceeds past field validation toward the DB transaction
994
+ (which then fails for lack of a configured database in this DB-free
995
+ test) — proof the guard targets 'sealed' specifically, not every
996
+ browser-fill password."""
997
+ import asyncio
998
+
999
+ from matrx_orm.secrets_battery import FieldSpec
1000
+ from matrx_orm.secrets_battery.items import (
1001
+ SealedBrowserFillPasswordError,
1002
+ create_credential_bundle,
1003
+ )
1004
+
1005
+ with pytest.raises(Exception) as excinfo:
1006
+ asyncio.run(
1007
+ create_credential_bundle(
1008
+ user_id="u1",
1009
+ display_name="AI Matrx",
1010
+ browser_fill_enabled=True,
1011
+ login_urls=["https://www.aimatrx.com/login"],
1012
+ fields=[
1013
+ FieldSpec("username", "me@example.com"),
1014
+ FieldSpec("password", "hunter2", handling="revealable"),
1015
+ ],
1016
+ )
1017
+ )
1018
+ assert not isinstance(excinfo.value, SealedBrowserFillPasswordError)
File without changes
File without changes
File without changes
File without changes
File without changes