ferro-orm 0.17.1__tar.gz → 0.19.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (403) hide show
  1. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/AGENTS.md +50 -2
  2. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/CHANGELOG.md +46 -0
  3. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/CONTEXT.md +23 -3
  4. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/Cargo.lock +116 -125
  5. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/Cargo.toml +1 -1
  6. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/PKG-INFO +1 -1
  7. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-ddl-lowering/src/lib.rs +1113 -1
  8. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/src/emit.rs +99 -3
  9. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/src/lib.rs +142 -1
  10. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/src/tests.rs +477 -1
  11. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-schema-ir/src/lib.rs +143 -0
  12. ferro_orm-0.19.0/docs/adr/0011-label-addition-update-gated-append-only.md +65 -0
  13. ferro_orm-0.19.0/docs/adr/0012-table-checks-are-lambdas.md +12 -0
  14. ferro_orm-0.19.0/docs/adr/0013-table-check-reconciliation.md +12 -0
  15. ferro_orm-0.19.0/docs/adr/0014-table-checks-sqlite-create-only.md +11 -0
  16. ferro_orm-0.19.0/docs/adr/0015-table-check-body-drift.md +11 -0
  17. ferro_orm-0.19.0/docs/adr/0016-check-predicates-literals-only.md +11 -0
  18. ferro_orm-0.19.0/docs/examples/table_checks.py +45 -0
  19. ferro_orm-0.19.0/docs/examples/table_checks_annotated.py +42 -0
  20. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/exceptions.md +18 -0
  21. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/migrations.md +78 -0
  22. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/models-and-fields.md +32 -0
  23. ferro_orm-0.19.0/docs/solutions/issues/pg18-restrict-sqlstate-23001.md +33 -0
  24. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/pyproject.toml +1 -1
  25. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/errors.rs +87 -7
  26. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/__init__.py +2 -0
  27. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_core.pyi +72 -1
  28. ferro_orm-0.19.0/src/ferro/checks.py +609 -0
  29. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/exceptions.py +6 -1
  30. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/ir/compiler.py +55 -0
  31. ferro_orm-0.19.0/src/ferro/migrations/alembic.py +664 -0
  32. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/models.py +12 -0
  33. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/introspect.rs +367 -0
  34. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/lib.rs +8 -1
  35. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/migrate.rs +161 -7
  36. ferro_orm-0.19.0/src/naming_ffi.rs +241 -0
  37. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/schema.rs +11 -3
  38. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/state.rs +1 -0
  39. ferro_orm-0.19.0/tests/test_check_predicate_dialect.py +348 -0
  40. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_cross_emitter_parity.py +20 -0
  41. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_exception_mapping.py +65 -0
  42. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_generation_counter_dirty_tracking.py +2 -10
  43. ferro_orm-0.19.0/tests/test_label_addition.py +380 -0
  44. ferro_orm-0.19.0/tests/test_live_table_checks.py +74 -0
  45. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_naming_single_source.py +19 -0
  46. ferro_orm-0.19.0/tests/test_table_check_orphans.py +546 -0
  47. ferro_orm-0.19.0/tests/test_table_check_rebuild.py +532 -0
  48. ferro_orm-0.19.0/tests/test_table_check_reconcile.py +514 -0
  49. ferro_orm-0.19.0/tests/test_table_checks.py +599 -0
  50. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/uv.lock +1 -1
  51. ferro_orm-0.17.1/src/ferro/migrations/alembic.py +0 -273
  52. ferro_orm-0.17.1/src/naming_ffi.rs +0 -92
  53. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  54. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  55. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/PERMISSIONS.md +0 -0
  56. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/PYPI_CHECKLIST.md +0 -0
  57. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/PYPI_SETUP.md +0 -0
  58. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/generated/wheels.generated.yml +0 -0
  59. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/pull_request_template.md +0 -0
  60. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/ci.yml +0 -0
  61. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/packaging-smoke.yml +0 -0
  62. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/publish-docs.yml +0 -0
  63. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/publish.yml +0 -0
  64. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/release.yml +0 -0
  65. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.gitignore +0 -0
  66. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.pre-commit-config.yaml +0 -0
  67. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.python-version +0 -0
  68. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/CONTRIBUTING.md +0 -0
  69. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/LICENSE +0 -0
  70. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/README.md +0 -0
  71. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/README.md +0 -0
  72. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/__init__.py +0 -0
  73. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/__main__.py +0 -0
  74. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/backends.py +0 -0
  75. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/baselines/postgres.json +0 -0
  76. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/baselines/sqlite.json +0 -0
  77. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/compare.py +0 -0
  78. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/harness.py +0 -0
  79. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/model.py +0 -0
  80. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/run.py +0 -0
  81. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-ddl-lowering/Cargo.toml +0 -0
  82. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/Cargo.toml +0 -0
  83. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/src/order.rs +0 -0
  84. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-schema-ir/Cargo.toml +0 -0
  85. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0001-resolved-epoch-registration.md +0 -0
  86. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0002-unified-column-fact-derivation.md +0 -0
  87. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0003-path-blind-db-type-validation.md +0 -0
  88. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0004-jsonb-postgres-only-canonical.md +0 -0
  89. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0005-jsonb-default-on-postgres.md +0 -0
  90. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0006-relation-traversal-inner-joins.md +0 -0
  91. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0007-materialization-plan-complete-instances.md +0 -0
  92. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0007-reverse-relations-tested-not-traversed.md +0 -0
  93. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0008-populated-relations-include.md +0 -0
  94. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0008-predicate-negation-uniform-not.md +0 -0
  95. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0009-aggregate-projections-derived-grouping.md +0 -0
  96. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0010-create-pass-owns-only-missing-tables.md +0 -0
  97. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/agents/domain.md +0 -0
  98. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/agents/issue-tracker.md +0 -0
  99. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/agents/triage-labels.md +0 -0
  100. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/architecture-review-2026-07-08.html +0 -0
  101. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-04-29-named-connections-role-routing-requirements.md +0 -0
  102. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-05-08-typed-query-predicates-requirements.md +0 -0
  103. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-05-13-configurable-column-storage-types-requirements.md +0 -0
  104. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-05-14-autogenerate-support-for-db-type-requirements.md +0 -0
  105. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-05-25-annotated-strenum-cold-hydration-requirements.md +0 -0
  106. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-24-ir-p8-119-wire-automigrate-requirements.md +0 -0
  107. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-25-ir-p8-120-parity-gate-requirements.md +0 -0
  108. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-26-ir-p8.5-140-shared-lowering-requirements.md +0 -0
  109. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-26-ir-p8.5-143-db-type-drop-requirements.md +0 -0
  110. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-26-ir-p8.5-144-reconcile-indexes-requirements.md +0 -0
  111. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-28-ir-p8.5-141-single-schema-ir-producer-requirements.md +0 -0
  112. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-29-ir-p8.6-146-dialect-enum-unification-requirements.md +0 -0
  113. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-29-ir-p8.6-153-create-path-ir-requirements.md +0 -0
  114. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-30-ir-p8.6-155-deferred-annotations-requirements.md +0 -0
  115. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-30-ir-p8.6-158-check-renderer-requirements.md +0 -0
  116. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-01-ir-p8.6-154-datetime-tz-coarseness-requirements.md +0 -0
  117. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-01-ir-p8.6-162-typed-save-bind-requirements.md +0 -0
  118. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-01-ir-p8.6-165-blob-introspection-false-positive-requirements.md +0 -0
  119. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-02-ff-c1-codec-plan-design.md +0 -0
  120. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-06-upgrade-guide-consolidation-requirements.md +0 -0
  121. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/aggregations.py +0 -0
  122. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/aggregations_annotated.py +0 -0
  123. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/existence_tests.py +0 -0
  124. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/existence_tests_annotated.py +0 -0
  125. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/multiple_databases.py +0 -0
  126. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/mutations.py +0 -0
  127. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/pagination.py +0 -0
  128. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/partial_selects.py +0 -0
  129. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/partial_selects_annotated.py +0 -0
  130. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/populated_relations.py +0 -0
  131. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/populated_relations_annotated.py +0 -0
  132. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/predicates.py +0 -0
  133. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/predicates_annotated.py +0 -0
  134. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/quickstart.py +0 -0
  135. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/quickstart_annotated.py +0 -0
  136. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/raw_sql.py +0 -0
  137. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/relationships.py +0 -0
  138. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/relationships_annotated.py +0 -0
  139. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/soft_deletes.py +0 -0
  140. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/soft_deletes_annotated.py +0 -0
  141. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/testing_conftest.py +0 -0
  142. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/timestamps.py +0 -0
  143. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/timestamps_annotated.py +0 -0
  144. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/transactions.py +0 -0
  145. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/traversal.py +0 -0
  146. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/traversal_annotated.py +0 -0
  147. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/connection.md +0 -0
  148. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/fields.md +0 -0
  149. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/migrations.md +0 -0
  150. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/model.md +0 -0
  151. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/queries.md +0 -0
  152. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/raw-sql.md +0 -0
  153. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/relationships.md +0 -0
  154. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/transactions.md +0 -0
  155. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/changelog.md +0 -0
  156. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/architecture.md +0 -0
  157. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/backends.md +0 -0
  158. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/identity-map.md +0 -0
  159. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/performance.md +0 -0
  160. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/query-typing.md +0 -0
  161. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/type-safety.md +0 -0
  162. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/contributing.md +0 -0
  163. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/faq.md +0 -0
  164. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/getting-started/installation.md +0 -0
  165. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/getting-started/next-steps.md +0 -0
  166. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/getting-started/quickstart.md +0 -0
  167. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/aggregations.md +0 -0
  168. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/connections.md +0 -0
  169. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/mutations.md +0 -0
  170. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/queries.md +0 -0
  171. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/raw-sql.md +0 -0
  172. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/relationships.md +0 -0
  173. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/transactions.md +0 -0
  174. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/migrate-from-sqlalchemy.md +0 -0
  175. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/multiple-databases.md +0 -0
  176. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/pagination.md +0 -0
  177. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/soft-deletes.md +0 -0
  178. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/testing.md +0 -0
  179. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/timestamps.md +0 -0
  180. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/upgrade-guide.md +0 -0
  181. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/index.md +0 -0
  182. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/roadmap.md +0 -0
  183. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/stylesheets/extra.css +0 -0
  184. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/why-ferro.md +0 -0
  185. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-04-24-001-refactor-multi-db-backend-architecture-plan.md +0 -0
  186. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-04-29-001-typed-null-binds-plan.md +0 -0
  187. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-04-29-002-feat-named-connections-plan.md +0 -0
  188. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-05-07-001-refactor-generic-model-connection-plan.md +0 -0
  189. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-05-08-001-feat-typed-query-predicates-plan.md +0 -0
  190. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-05-13-001-feat-configurable-column-storage-types-plan.md +0 -0
  191. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-05-25-001-fix-annotated-strenum-cold-hydration-plan.md +0 -0
  192. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-19-001-ir-first-roadmap.md +0 -0
  193. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-24-001-feat-ir-p8-119-wire-automigrate-plan.md +0 -0
  194. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-25-001-feat-ir-p8-120-parity-gate-plan.md +0 -0
  195. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-26-001-feat-ir-p8.5-140-shared-lowering-plan.md +0 -0
  196. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-26-002-feat-ir-p8.5-143-db-type-drop-plan.md +0 -0
  197. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-26-003-feat-ir-p8.5-144-reconcile-indexes-plan.md +0 -0
  198. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-28-001-feat-ir-p8.5-141-single-schema-ir-producer-plan.md +0 -0
  199. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-29-001-refactor-ir-p8.6-153-create-path-unification-plan.md +0 -0
  200. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-29-002-refactor-ir-p8.6-146-dialect-enum-unification-plan.md +0 -0
  201. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-30-001-refactor-ir-p8.6-158-check-renderer-plan.md +0 -0
  202. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-30-002-fix-ir-p8.6-155-deferred-annotations-plan.md +0 -0
  203. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-01-001-feat-ir-p8.6-162-typed-save-bind-plan.md +0 -0
  204. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-01-002-fix-ir-p8.6-154-datetime-tz-coarseness-plan.md +0 -0
  205. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-01-003-fix-ir-p8.6-165-blob-introspection-plan.md +0 -0
  206. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-001-fable-fixes-roadmap.md +0 -0
  207. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-002-feat-ff-a-172-typed-exceptions-plan.md +0 -0
  208. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-003-ff-c-native-decode-design.md +0 -0
  209. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-004-ff-c-c2-catalog-cache-design.md +0 -0
  210. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-005-ff-d-identity-routing-design.md +0 -0
  211. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-006-ff-d-identity-routing-plan.md +0 -0
  212. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-03-007-ff-e-registry-identity-design.md +0 -0
  213. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-03-008-ff-e-registry-identity-plan.md +0 -0
  214. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-009-ff-f-query-builder-1.0-design.md +0 -0
  215. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-010-ff-f-query-builder-1.0-plan.md +0 -0
  216. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-011-ff-g-hardening-design.md +0 -0
  217. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-012-ff-g-hardening-plan.md +0 -0
  218. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-013-ff-g2-operations-dedup-design.md +0 -0
  219. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-014-ff-g2-operations-dedup-plan.md +0 -0
  220. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-015-docs-upgrade-guide-consolidation-plan.md +0 -0
  221. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-18-016-existence-tests-design.md +0 -0
  222. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/ir-first-migration-guide.md +0 -0
  223. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/ir-first-release-checklist.md +0 -0
  224. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/rfc/ir-contracts-v1.md +0 -0
  225. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/README.md +0 -0
  226. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/architecture-patterns/ir-first-lowering-consolidation-audit.md +0 -0
  227. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/architecture-patterns/ir-first-merge-readiness-review.md +0 -0
  228. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/pydantic-slots-missing-after-ferro-hydration.md +0 -0
  229. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/python-3.14-deferred-annotation-typeerror-swallow.md +0 -0
  230. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/sa-pk-column-nullable-divergence.md +0 -0
  231. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/sa-vs-rust-unique-constraint-shape.md +0 -0
  232. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/self-fk-evicts-component-from-create-order.md +0 -0
  233. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/sqlite-integer-decimal-hydrates-as-none.md +0 -0
  234. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/sqlite-null-hydrates-as-int-zero.md +0 -0
  235. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/typed-where-null-panics-is-null.md +0 -0
  236. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/configurable-column-storage-types.md +0 -0
  237. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/cross-emitter-ddl-parity.md +0 -0
  238. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/ddl-on-live-engine.md +0 -0
  239. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/derived-type-and-naming-decision-table.md +0 -0
  240. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/foreign-key-index.md +0 -0
  241. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/index-unique-redundancy.md +0 -0
  242. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/ir-invariants.md +0 -0
  243. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/persistence-state.md +0 -0
  244. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/shadow-fk-columns.md +0 -0
  245. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/sqlite-alembic-reconnect-hydration-tests.md +0 -0
  246. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/typed-null-binds.md +0 -0
  247. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/justfile +0 -0
  248. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/scripts/demo_queries.py +0 -0
  249. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/scripts/demo_queries_pre_v012.py +0 -0
  250. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/backend.rs +0 -0
  251. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/codec.rs +0 -0
  252. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/codec_plan.rs +0 -0
  253. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/connection.rs +0 -0
  254. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_annotation_utils.py +0 -0
  255. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_bind_payload.py +0 -0
  256. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_deprecations.py +0 -0
  257. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_shadow_fk_types.py +0 -0
  258. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/base.py +0 -0
  259. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/columns.py +0 -0
  260. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/composite_indexes.py +0 -0
  261. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/composite_uniques.py +0 -0
  262. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/fields.py +0 -0
  263. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/ir/__init__.py +0 -0
  264. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/metaclass.py +0 -0
  265. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/migrations/__init__.py +0 -0
  266. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/py.typed +0 -0
  267. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/__init__.py +0 -0
  268. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/builder.py +0 -0
  269. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/nodes.py +0 -0
  270. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/rows.py +0 -0
  271. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/wire.py +0 -0
  272. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/raw.py +0 -0
  273. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/registry.py +0 -0
  274. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/relations/__init__.py +0 -0
  275. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/relations/descriptors.py +0 -0
  276. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/session.py +0 -0
  277. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/state.py +0 -0
  278. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/hydration.rs +0 -0
  279. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/operations.rs +0 -0
  280. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/query.rs +0 -0
  281. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/schema_bind.rs +0 -0
  282. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/__init__.py +0 -0
  283. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/conftest.py +0 -0
  284. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/db_backends.py +0 -0
  285. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/README.md +0 -0
  286. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/codec_registry_core_v1.json +0 -0
  287. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_account_exists_v7.json +0 -0
  288. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_account_scoped_exists_v7.json +0 -0
  289. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_owner_nested_exists_v7.json +0 -0
  290. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_owner_not_exists_v7.json +0 -0
  291. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_aggregate_v7.json +0 -0
  292. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_global_aggregate_v7.json +0 -0
  293. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_include_v7.json +0 -0
  294. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_left_join_v7.json +0 -0
  295. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_record_v7.json +0 -0
  296. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_traversal_v7.json +0 -0
  297. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_traversed_record_v7.json +0 -0
  298. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_user_compound_v7.json +0 -0
  299. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_user_m2m_exists_v7.json +0 -0
  300. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_user_not_compound_v7.json +0 -0
  301. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_user_not_leaf_v7.json +0 -0
  302. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/schema_invoice_baseline_v1.json +0 -0
  303. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/schema_phase1_fixture_models_v1.json +0 -0
  304. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/schema_raw_str_pk_autoincrement_v1.json +0 -0
  305. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/bad_includes.py +0 -0
  306. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/bad_predicates.py +0 -0
  307. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/bad_projections.py +0 -0
  308. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/good_includes.py +0 -0
  309. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/good_predicates.py +0 -0
  310. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/good_projections.py +0 -0
  311. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_aggregation.py +0 -0
  312. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_autogenerate.py +0 -0
  313. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_bridge.py +0 -0
  314. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_db_type.py +0 -0
  315. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_nullability.py +0 -0
  316. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_type_mapping.py +0 -0
  317. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_annotation_utils.py +0 -0
  318. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_auto_migrate.py +0 -0
  319. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_bulk_create_chunking.py +0 -0
  320. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_bulk_install.py +0 -0
  321. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_bulk_update.py +0 -0
  322. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_catalog_cache.py +0 -0
  323. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_codec_plan.py +0 -0
  324. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_column_specs.py +0 -0
  325. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_compiled_query.py +0 -0
  326. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_composite_index.py +0 -0
  327. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_composite_unique.py +0 -0
  328. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_connection.py +0 -0
  329. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_connection_redaction.py +0 -0
  330. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_constraints.py +0 -0
  331. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_crud.py +0 -0
  332. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_backends.py +0 -0
  333. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_type_cross_emitter_parity.py +0 -0
  334. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_type_integration.py +0 -0
  335. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_type_typing.py +0 -0
  336. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_type_validation.py +0 -0
  337. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_deletion.py +0 -0
  338. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_deprecations.py +0 -0
  339. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_docs_examples.py +0 -0
  340. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_documentation_features.py +0 -0
  341. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_enum_cold_hydration.py +0 -0
  342. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_exceptions.py +0 -0
  343. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_field_wrapper.py +0 -0
  344. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_fk_target_pk.py +0 -0
  345. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_global_aggregates.py +0 -0
  346. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_grouped_aggregates.py +0 -0
  347. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_helpers.py +0 -0
  348. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_hydration.py +0 -0
  349. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_hydration_equivalence.py +0 -0
  350. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_identity_memory.py +0 -0
  351. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_identity_refresh.py +0 -0
  352. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_identity_scoped_invalidation.py +0 -0
  353. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_identity_weakref.py +0 -0
  354. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_import_budget.py +0 -0
  355. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_include.py +0 -0
  356. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_ir_vectors_contract.py +0 -0
  357. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_metaclass_internals.py +0 -0
  358. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_metadata.py +0 -0
  359. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_migrate_plan.py +0 -0
  360. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_model_identity.py +0 -0
  361. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_models.py +0 -0
  362. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_mutation_pagination_guard.py +0 -0
  363. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_named_connections_integration.py +0 -0
  364. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_negation.py +0 -0
  365. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_one_to_one.py +0 -0
  366. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_operation_seam_sync.py +0 -0
  367. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_partial_selects.py +0 -0
  368. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_primary_key_facts.py +0 -0
  369. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_provisional_import.py +0 -0
  370. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_builder.py +0 -0
  371. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_column_validation.py +0 -0
  372. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_exists.py +0 -0
  373. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_immutability.py +0 -0
  374. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_joins.py +0 -0
  375. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_typing.py +0 -0
  376. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_wire_vectors.py +0 -0
  377. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_raw_sql.py +0 -0
  378. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_refresh.py +0 -0
  379. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_registry_entrypoints.py +0 -0
  380. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_registry_owner.py +0 -0
  381. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_relation_specs.py +0 -0
  382. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_relationship_engine.py +0 -0
  383. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_relationship_resolution_errors.py +0 -0
  384. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_route_single_site.py +0 -0
  385. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_routing_errors.py +0 -0
  386. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_save_pk_edges.py +0 -0
  387. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_save_semantics.py +0 -0
  388. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_schema.py +0 -0
  389. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_schema_constraints.py +0 -0
  390. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_schema_db_type_metadata.py +0 -0
  391. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_schema_enum_annotations.py +0 -0
  392. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_session.py +0 -0
  393. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_shadow_fk_types.py +0 -0
  394. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_sqlite_alembic_reconnect_hydration.py +0 -0
  395. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_static_contracts.py +0 -0
  396. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_string_search.py +0 -0
  397. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_structural_types.py +0 -0
  398. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_temporal_types.py +0 -0
  399. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_transactions.py +0 -0
  400. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_traversed_projection.py +0 -0
  401. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_typed_null_binds.py +0 -0
  402. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_typed_save_bind.py +0 -0
  403. {ferro_orm-0.17.1 → ferro_orm-0.19.0}/zensical.toml +0 -0
@@ -46,10 +46,58 @@ For a single model, every emitter must agree on:
46
46
  `docs/solutions/patterns/derived-type-and-naming-decision-table.md`.
47
47
  7. **Primary key constraint names** — when explicitly named.
48
48
  8. **Check constraint names** — `ck_<table>_<col>` for the single-column
49
- `db_check=True` constraint; generated by `_ck_constraint_name` (Python)
50
- and `db_check_constraint_name` (Rust).
49
+ `db_check=True` constraint; `ck_<table>_<suffix>` for table checks declared
50
+ in `__ferro_checks__`. Column checks use `_ddl_check_constraint_name`
51
+ (Python) and `db_check_constraint_name` (Rust); table checks use
52
+ `_ddl_table_check_constraint_name` (Python) and
53
+ `table_check_constraint_name` (Rust).
51
54
  9. **Default values** — server-side defaults must serialize identically.
52
55
  10. **Nullability** — must agree.
56
+ 11. **Enum label additions** — the label-addition decision (which model-declared
57
+ labels a live enum type is missing, and which live labels are extra) and
58
+ the rendered `ALTER TYPE ... ADD VALUE IF NOT EXISTS` statement are decided
59
+ by ONE pair of functions: `ferro_ddl_lowering::missing_enum_labels` /
60
+ `extra_enum_labels` + `render_pg_enum_add_value`. The auto-migrate
61
+ reconciliation pass consumes them directly; the Alembic autogenerate
62
+ comparator consumes them over FFI (`_core._plan_enum_label_addition`) and
63
+ executes the byte-identical statements. Pinned by
64
+ `tests/test_cross_emitter_parity.py` and the ferro-ddl-lowering unit pins.
65
+ See ADR-0011 (append-only; update-gated; warn-never-act for extras).
66
+ 12. **Check additions** — the missing-check decision (which declared `ck_*`
67
+ names — table checks, then column checks — a live table does not carry)
68
+ and the rendered ADD are decided by ONE pair of functions:
69
+ `ferro_ddl_lowering::missing_check_names` / `render_check_addition`.
70
+ The auto-migrate reconciliation pass consumes them through
71
+ `ferro_migrate::plan_missing_checks`; the Alembic autogenerate
72
+ comparator consumes them over FFI (`_core._plan_check_addition`) and
73
+ executes the byte-identical statements. Pinned by
74
+ `tests/test_table_check_reconcile.py`. See ADR-0013 (add on
75
+ `migrate_updates`; name-only comparison) and ADR-0014 (SQLite warn-skip).
76
+ 13. **Check rebuilds** — the same-name body-drift decision (which declared
77
+ `ck_*` names exist live **and** whose catalog definition normalizes
78
+ unequal to the canonical rendering) and the rendered DROP + bare ADD
79
+ are decided by ONE pair of functions:
80
+ `ferro_ddl_lowering::drifted_check_names` / `render_check_rebuild`
81
+ (one normalizer: `normalize_check_definition`). The auto-migrate
82
+ reconciliation pass consumes them through
83
+ `ferro_migrate::plan_check_rebuilds`; the Alembic autogenerate
84
+ comparator consumes them over FFI (`_core._plan_check_rebuild`) and
85
+ executes the byte-identical statements. Pinned by
86
+ `tests/test_table_check_rebuild.py`. See ADR-0015 (canonical render vs
87
+ catalog, both through one normalizer) and ADR-0014 (SQLite warn-skip).
88
+ 14. **Check leftovers / drops** — the leftover-name decision (which live
89
+ ferro-owned `ck_*` names a table carries that the model no longer
90
+ declares) and the rendered DROP are decided by ONE trio of functions:
91
+ `ferro_ddl_lowering::extra_check_names` /
92
+ `extra_check_names_warning` / `render_check_drop`. The auto-migrate
93
+ reconciliation pass consumes them through
94
+ `ferro_migrate::plan_check_drops` (ops only under
95
+ `migrate_destructive`; the warning always fires on `migrate_updates`).
96
+ The Alembic autogenerate comparator consumes them over FFI
97
+ (`_core._plan_check_drop`) with **no** destructive gate and executes
98
+ the byte-identical statements. Pinned by
99
+ `tests/test_table_check_orphans.py`. See ADR-0013 (leftover warning +
100
+ destructive ladder) and ADR-0014 (SQLite warn-skip).
53
101
 
54
102
  ### Why this invariant exists
55
103
 
@@ -1,6 +1,52 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v0.19.0 (2026-08-18)
5
+
6
+ ### Bug Fixes
7
+
8
+ - Classify PG18 RESTRICT (23001) as ForeignKeyViolationError
9
+ ([#338](https://github.com/syn54x/ferro-orm/pull/338),
10
+ [`4fa1153`](https://github.com/syn54x/ferro-orm/commit/4fa1153477802de8207c7987748db962b35c2f0f))
11
+
12
+ ### Features
13
+
14
+ - Named table-level CHECK constraints ([#356](https://github.com/syn54x/ferro-orm/pull/356),
15
+ [`ba179e7`](https://github.com/syn54x/ferro-orm/commit/ba179e71e9bce4ab77a6fdbc1831661485de6799))
16
+
17
+
18
+ ## v0.18.0 (2026-08-05)
19
+
20
+ ### Documentation
21
+
22
+ - **adr**: ADR-0011 label addition + glossary terms (enum label, label addition)
23
+ ([`449616f`](https://github.com/syn54x/ferro-orm/commit/449616f07aefe473fe098f45f6873eb2003cf8e5))
24
+
25
+ - **migrate**: Label addition — the auto_migrate trap, the migrate_updates contract, the ordering
26
+ caveat ([#334](https://github.com/syn54x/ferro-orm/pull/334),
27
+ [`482911b`](https://github.com/syn54x/ferro-orm/commit/482911b441eeeed21b13d3927c9492797bb1eba5))
28
+
29
+ ### Features
30
+
31
+ - **alembic**: Autogenerate comparator emits label additions from the shared diff
32
+ ([#333](https://github.com/syn54x/ferro-orm/pull/333),
33
+ [`1579fc3`](https://github.com/syn54x/ferro-orm/commit/1579fc38a7f0d2b94c4ea51aa7daac652df30abc))
34
+
35
+ - **migrate**: Label addition tracer — migrate_updates appends missing enum labels
36
+ ([#330](https://github.com/syn54x/ferro-orm/pull/330),
37
+ [`e929a6a`](https://github.com/syn54x/ferro-orm/commit/e929a6ae854fd435c6aac3277e476c15b106f73a))
38
+
39
+ - **migrate**: Warn-never-act for extra enum labels; create pass stays silent
40
+ ([#331](https://github.com/syn54x/ferro-orm/pull/331),
41
+ [`a73d142`](https://github.com/syn54x/ferro-orm/commit/a73d142e2ff22ef8e47c2a8b8c34ca92372d0487))
42
+
43
+ ### Testing
44
+
45
+ - **migrate**: Label addition edges — shared types, default-in-same-run, ordering, idempotence
46
+ ([#332](https://github.com/syn54x/ferro-orm/pull/332),
47
+ [`1215f0c`](https://github.com/syn54x/ferro-orm/commit/1215f0c0e52367eafd91411b7b7891220edf318e))
48
+
49
+
4
50
  ## v0.17.1 (2026-07-19)
5
51
 
6
52
  ### Bug Fixes
@@ -129,13 +129,33 @@ The auto-migrate step that brings missing tables into existence — the table, i
129
129
  _Avoid_: Bootstrap, ensure-tables, table sync
130
130
 
131
131
  **Reconciliation pass**:
132
- The `migrate_updates` step that alters existing tables to match the registered models — the only authority for DDL against a table that already exists. Within one table, column changes land before the indexes and constraints that reference them.
132
+ The `migrate_updates` step that alters existing schema objects — tables and ferro-owned enum types — to match the registered models; the only authority for DDL against an object that already exists. Within one table, column changes land before the indexes and constraints that reference them; label additions land before any table's changes.
133
133
  _Avoid_: Update pass, schema sync, drift repair
134
134
 
135
135
  **Ferro-owned artifact**:
136
- An index or constraint whose name follows ferro's canonical naming (`idx_`, `uq_`, `fk_`, `ck_`), marking it as reconcilable: auto-migrate may create, rebuild, or drop it to match the declared model. Artifacts named any other way belong to the user and are never altered or dropped.
136
+ A schema object ferro may reconcile to match the declared model. Indexes and constraints are ferro-owned by naming (`idx_`, `uq_`, `fk_`, `ck_`); native enum types are ferro-owned by derivation — the type's name matches the name ferro derives from the model. Artifacts owned neither way belong to the user and are never altered or dropped.
137
137
  _Avoid_: Managed index, system constraint, internal index
138
138
 
139
+ **Enum label**:
140
+ One storable value of a native Postgres enum type, mirrored from a Python `StrEnum` member's value. Members are the Python-side declaration; labels are what the database accepts and stores.
141
+ _Avoid_: Enum value, variant, choice
142
+
143
+ **Label addition**:
144
+ The reconciliation-pass operation appending model-declared labels missing from a live ferro-owned enum type. Append-only and metadata-only: rows are never touched, and labels the database has but the model lacks are warned about loudly and never removed — removal and rename are reviewed-migration territory.
145
+ _Avoid_: Enum sync, label reconciliation, enum evolution
146
+
139
147
  **Constraint rebuild**:
140
- Drop-and-recreate of a ferro-owned constraint whose live definition no longer matches the declared model — a foreign key's `on_delete`, its target, its columns. Metadata-only: rows are never touched. On a backend that cannot alter constraints, ferro warns loudly and skips; it never diverges silently.
148
+ Drop-and-recreate of a ferro-owned constraint whose live definition no longer matches the declared model — a foreign key's `on_delete`, its target, its columns, or a table check's predicate. Metadata-only: rows are never touched. On a backend that cannot alter constraints, ferro warns loudly and skips; it never diverges silently.
141
149
  _Avoid_: Constraint alter, FK patch, in-place constraint update
150
+
151
+ **Column check**:
152
+ A single-column CHECK that restricts a closed-domain field to its declared labels (`Field(db_check=True)` → `col IN (...)`). Named `ck_<table>_<col>`; not a table check.
153
+ _Avoid_: enum check, db_check constraint, value check
154
+
155
+ **Table check**:
156
+ A named boolean invariant over one row of one table, declared on the model as a lambda and enforced by the database as a CHECK constraint. The live name is `ck_<table>_<suffix>`; the suffix is what the model declares.
157
+ _Avoid_: table-level check, multi-column check, composite check, row check
158
+
159
+ **Check predicate**:
160
+ The lambda body of a table check — a ferro predicate over that model's own columns (or a forward-FK null test on the relation or its shadow `*_id`), with literal values only. Relation traversal, existence tests, and aggregates are not check predicates.
161
+ _Avoid_: check SQL, constraint expression, check body