metaobjects 0.16.0__tar.gz → 0.18.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 (392) hide show
  1. {metaobjects-0.16.0 → metaobjects-0.18.0}/PKG-INFO +1 -1
  2. {metaobjects-0.16.0 → metaobjects-0.18.0}/pyproject.toml +1 -1
  3. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/entity_model.py +37 -5
  4. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +6 -1
  5. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/router_generator.py +6 -1
  6. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/core_types.py +72 -7
  7. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/errors.py +21 -0
  8. metaobjects-0.18.0/src/metaobjects/loader/validate_source_escapes.py +205 -0
  9. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/validation_passes.py +536 -9
  10. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/attr/attr_constants.py +5 -0
  11. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/attr/meta_attr.py +12 -0
  12. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/field/meta_field.py +15 -0
  13. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/object/meta_object.py +22 -0
  14. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/object/object_constants.py +6 -0
  15. metaobjects-0.18.0/src/metaobjects/meta/persistence/origin/origin_constants.py +49 -0
  16. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/source/meta_source.py +20 -0
  17. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/source/source_constants.py +10 -0
  18. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/runtime/object_manager.py +176 -11
  19. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/attr.json +6 -0
  20. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/db.json +2 -0
  21. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/object.json +4 -1
  22. metaobjects-0.18.0/src/metaobjects/spec_metamodel/origin.json +67 -0
  23. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/ui.json +2 -1
  24. metaobjects-0.18.0/tests/codegen/test_origin_nullability.py +129 -0
  25. metaobjects-0.18.0/tests/codegen/test_write_through.py +112 -0
  26. metaobjects-0.18.0/tests/integration/api_contract_jsonb_server.py +317 -0
  27. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/generated_jsonb_app.py +22 -6
  28. metaobjects-0.18.0/tests/unit/test_object_manager_autoset_stamping.py +239 -0
  29. metaobjects-0.18.0/tests/unit/test_object_manager_write_through.py +167 -0
  30. metaobjects-0.18.0/tests/unit/test_source_escapes.py +336 -0
  31. metaobjects-0.18.0/tests/unit/test_validation_origin_195.py +312 -0
  32. metaobjects-0.16.0/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -28
  33. metaobjects-0.16.0/src/metaobjects/spec_metamodel/origin.json +0 -43
  34. metaobjects-0.16.0/tests/integration/api_contract_jsonb_server.py +0 -160
  35. {metaobjects-0.16.0 → metaobjects-0.18.0}/.gitignore +0 -0
  36. {metaobjects-0.16.0 → metaobjects-0.18.0}/LICENSE +0 -0
  37. {metaobjects-0.16.0 → metaobjects-0.18.0}/README.md +0 -0
  38. {metaobjects-0.16.0 → metaobjects-0.18.0}/hatch_build.py +0 -0
  39. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/__init__.py +0 -0
  40. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/agent_context/__init__.py +0 -0
  41. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/agent_context/scaffold.py +0 -0
  42. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/apidocs/__init__.py +0 -0
  43. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/apidocs/api_model.py +0 -0
  44. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/apidocs/builder.py +0 -0
  45. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/apidocs/naming.py +0 -0
  46. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/apidocs/paths.py +0 -0
  47. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/apidocs/renderer.py +0 -0
  48. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/attr_class_map.py +0 -0
  49. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/cli.py +0 -0
  50. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
  51. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/__init__.py +0 -0
  52. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/config.py +0 -0
  53. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/constants.py +0 -0
  54. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
  55. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
  56. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/format.py +0 -0
  57. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
  58. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generator.py +0 -0
  59. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generator_registry.py +0 -0
  60. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/__init__.py +0 -0
  61. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
  62. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
  63. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
  64. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
  65. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
  66. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/payload_vo_generator.py +0 -0
  67. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
  68. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/template_generator.py +0 -0
  69. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
  70. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
  71. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/instance_artifacts.py +0 -0
  72. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
  73. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/overwrite_policy.py +0 -0
  74. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/runner.py +0 -0
  75. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/runtime/__init__.py +0 -0
  76. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
  77. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
  78. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
  79. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
  80. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
  81. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/codegen/type_map.py +0 -0
  82. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/datatype.py +0 -0
  83. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/documentation/__init__.py +0 -0
  84. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/documentation/doc_constants.py +0 -0
  85. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/documentation/doc_provider.py +0 -0
  86. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/documentation/doc_schema.py +0 -0
  87. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/__init__.py +0 -0
  88. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/merge.py +0 -0
  89. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/meta_data_loader.py +0 -0
  90. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/registered_validation.py +0 -0
  91. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/sources/__init__.py +0 -0
  92. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/sources/directory_source.py +0 -0
  93. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/sources/file_source.py +0 -0
  94. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
  95. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/sources/uri_source.py +0 -0
  96. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/validate_discriminator.py +0 -0
  97. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/validate_field_readonly.py +0 -0
  98. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
  99. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
  100. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/__init__.py +0 -0
  101. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/__init__.py +0 -0
  102. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/attr/__init__.py +0 -0
  103. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/field/__init__.py +0 -0
  104. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/field/field_constants.py +0 -0
  105. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/identity/__init__.py +0 -0
  106. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
  107. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
  108. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/index/__init__.py +0 -0
  109. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/index/index_constants.py +0 -0
  110. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/index/meta_index.py +0 -0
  111. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/object/__init__.py +0 -0
  112. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
  113. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
  114. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/object/object_extract.py +0 -0
  115. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/object/value_object.py +0 -0
  116. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
  117. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
  118. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
  119. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
  120. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/validator/__init__.py +0 -0
  121. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
  122. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/meta_data.py +0 -0
  123. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/meta_root.py +0 -0
  124. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/__init__.py +0 -0
  125. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
  126. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
  127. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
  128. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
  129. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
  130. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
  131. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/__init__.py +0 -0
  132. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
  133. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
  134. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
  135. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
  136. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
  137. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
  138. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
  139. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
  140. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/provider_extends.py +0 -0
  141. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/template/__init__.py +0 -0
  142. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/template/meta_template.py +0 -0
  143. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/template/prompt_provider.py +0 -0
  144. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/meta/template/template_constants.py +0 -0
  145. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/naming_refs.py +0 -0
  146. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/parser.py +0 -0
  147. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/parser_yaml.py +0 -0
  148. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/provider.py +0 -0
  149. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/py.typed +0 -0
  150. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/registry.py +0 -0
  151. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/registry_manifest.py +0 -0
  152. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/__init__.py +0 -0
  153. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/email_document.py +0 -0
  154. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/escapers.py +0 -0
  155. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
  156. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/__init__.py +0 -0
  157. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/coerce.py +0 -0
  158. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/extract.py +0 -0
  159. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/extract_map.py +0 -0
  160. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
  161. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/locate.py +0 -0
  162. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/normalize.py +0 -0
  163. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/strip.py +0 -0
  164. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/types.py +0 -0
  165. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
  166. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/filesystem_provider.py +0 -0
  167. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/prompt/__init__.py +0 -0
  168. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
  169. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
  170. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/prompt/prompt_field.py +0 -0
  171. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
  172. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/prompt/prompt_style.py +0 -0
  173. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/renderer.py +0 -0
  174. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/render/verify.py +0 -0
  175. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/runtime/__init__.py +0 -0
  176. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/runtime/llm_recorder.py +0 -0
  177. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/runtime/n2m_resolver.py +0 -0
  178. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/runtime/tph.py +0 -0
  179. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/serializer_json.py +0 -0
  180. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/shared/__init__.py +0 -0
  181. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/shared/base_types.py +0 -0
  182. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/shared/separators.py +0 -0
  183. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/shared/structural.py +0 -0
  184. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/source/__init__.py +0 -0
  185. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/source/error_source.py +0 -0
  186. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/source/json_path.py +0 -0
  187. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/source/semantic_diff.py +0 -0
  188. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/source/yaml_positions.py +0 -0
  189. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/__init__.py +0 -0
  190. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/documentation.json +0 -0
  191. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/field.json +0 -0
  192. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/identity.json +0 -0
  193. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/index.json +0 -0
  194. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/layout.json +0 -0
  195. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/prompt.json +0 -0
  196. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/relationship.json +0 -0
  197. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/source.json +0 -0
  198. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/template.json +0 -0
  199. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/validator.json +0 -0
  200. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/spec_metamodel/view.json +0 -0
  201. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/super_resolve.py +0 -0
  202. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/validation_types.py +0 -0
  203. {metaobjects-0.16.0 → metaobjects-0.18.0}/src/metaobjects/yaml_desugar.py +0 -0
  204. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/__init__.py +0 -0
  205. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/__init__.py +0 -0
  206. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
  207. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/extends/expected/Program.py +0 -0
  208. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/extends/meta.json +0 -0
  209. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
  210. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
  211. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/nested-array/meta.json +0 -0
  212. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
  213. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/scalars/expected/Report.py +0 -0
  214. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/scalars/meta.json +0 -0
  215. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
  216. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/golden/vanilla/meta.json +0 -0
  217. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_abstract_conformance.py +0 -0
  218. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_api_docs_builder.py +0 -0
  219. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_api_docs_paths.py +0 -0
  220. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_cli.py +0 -0
  221. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_cli_providers.py +0 -0
  222. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_cli_registry.py +0 -0
  223. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_cli_staleness_nudge.py +0 -0
  224. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_cli_verify_strict.py +0 -0
  225. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_cli_verify_subverbs.py +0 -0
  226. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_constants_config.py +0 -0
  227. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_entity_model.py +0 -0
  228. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_enum_conformance.py +0 -0
  229. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
  230. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_extractor_generator.py +0 -0
  231. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_filter_allowlist_generator.py +0 -0
  232. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_format.py +0 -0
  233. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
  234. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_fr010_output_codegen.py +0 -0
  235. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
  236. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_generator.py +0 -0
  237. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_generator_extension_seams.py +0 -0
  238. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_golden.py +0 -0
  239. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
  240. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_inheritance_conformance.py +0 -0
  241. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_instance_artifacts.py +0 -0
  242. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_m2m_codegen.py +0 -0
  243. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_output_parser_generator.py +0 -0
  244. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_overwrite_policy.py +0 -0
  245. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_payload_vo_generator.py +0 -0
  246. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_projection_compile.py +0 -0
  247. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_render_helper_conformance.py +0 -0
  248. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_render_helper_generator.py +0 -0
  249. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_reverse_finders.py +0 -0
  250. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_router_generator.py +0 -0
  251. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_runner.py +0 -0
  252. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_template_data.py +0 -0
  253. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_template_generator.py +0 -0
  254. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_template_output_pattern.py +0 -0
  255. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_template_scope_helpers.py +0 -0
  256. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_template_scope_walk.py +0 -0
  257. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_template_spec.py +0 -0
  258. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_tph_codegen.py +0 -0
  259. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_trace_helper_generator.py +0 -0
  260. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_type_map.py +0 -0
  261. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/codegen/test_validation_conformance.py +0 -0
  262. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/__init__.py +0 -0
  263. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/capabilities.py +0 -0
  264. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/conformance-expected-failures.json +0 -0
  265. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/conformance_adapter.py +0 -0
  266. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/corpus.py +0 -0
  267. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/expected_failures.py +0 -0
  268. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/fixture_discovery.py +0 -0
  269. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/navigator.py +0 -0
  270. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
  271. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_conformance.py +0 -0
  272. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_extract_conformance.py +0 -0
  273. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_extract_object_verdict.py +0 -0
  274. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_fr010_loader_attrs.py +0 -0
  275. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_fr011_attrs.py +0 -0
  276. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_generator_registry_conformance.py +0 -0
  277. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_object_model_conformance.py +0 -0
  278. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_provider_composition_conformance.py +0 -0
  279. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_registry_conformance.py +0 -0
  280. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_runner_hardfail.py +0 -0
  281. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_spec_metamodel_embed.py +0 -0
  282. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_strict_attr_load.py +0 -0
  283. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_template_codegen_conformance.py +0 -0
  284. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_template_generator_conformance.py +0 -0
  285. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/test_yaml_conformance.py +0 -0
  286. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
  287. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/__init__.py +0 -0
  288. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/api_contract_assertions.py +0 -0
  289. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/api_contract_m2m_server.py +0 -0
  290. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/api_contract_server.py +0 -0
  291. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/generated_m2m_app.py +0 -0
  292. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/generated_router_app.py +0 -0
  293. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/generated_tph_app.py +0 -0
  294. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/meta_ai_trace.yaml +0 -0
  295. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/normalization.py +0 -0
  296. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/postgres_container.py +0 -0
  297. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/query_runner.py +0 -0
  298. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/scenarios.py +0 -0
  299. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_api_contract.py +0 -0
  300. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_api_contract_generated.py +0 -0
  301. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_api_contract_jsonb.py +0 -0
  302. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_api_contract_m2m.py +0 -0
  303. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_api_contract_m2m_generated.py +0 -0
  304. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_api_contract_tph_generated.py +0 -0
  305. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_generated_router_uuid_pk.py +0 -0
  306. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_llm_call_trace.py +0 -0
  307. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_normalization.py +0 -0
  308. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_query_scenarios.py +0 -0
  309. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/integration/test_runtime_return_types.py +0 -0
  310. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/open_closed_proof_test.py +0 -0
  311. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/__init__.py +0 -0
  312. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/__init__.py +0 -0
  313. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_coerce.py +0 -0
  314. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_extract.py +0 -0
  315. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_extract_map.py +0 -0
  316. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_json_forgiving_reader.py +0 -0
  317. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_locate.py +0 -0
  318. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_model.py +0 -0
  319. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_normalize.py +0 -0
  320. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_strip.py +0 -0
  321. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
  322. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/prompt/__init__.py +0 -0
  323. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/prompt/test_output_format_renderer.py +0 -0
  324. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/test_email_document.py +0 -0
  325. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/test_filesystem_provider.py +0 -0
  326. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/test_output_format_renderer_nested.py +0 -0
  327. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/test_output_prompt_conformance.py +0 -0
  328. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/test_render_conformance.py +0 -0
  329. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/test_render_max_chars.py +0 -0
  330. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/test_verify.py +0 -0
  331. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/render/test_verify_conformance.py +0 -0
  332. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/source/__init__.py +0 -0
  333. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/source/test_fr5c_merge_attribution.py +0 -0
  334. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/source/test_fr5d_reference_resolution.py +0 -0
  335. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/source/test_fr5e_database_source_shape.py +0 -0
  336. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/source/test_json_path.py +0 -0
  337. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/source/test_semantic_diff.py +0 -0
  338. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/source/test_source_on_node.py +0 -0
  339. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/source/test_yaml_positions.py +0 -0
  340. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/test_api_docs_accuracy.py +0 -0
  341. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/__init__.py +0 -0
  342. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_agent_context_staleness.py +0 -0
  343. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_capabilities.py +0 -0
  344. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_common_attrs.py +0 -0
  345. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_core_types.py +0 -0
  346. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_effective_package.py +0 -0
  347. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_errors.py +0 -0
  348. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_field_enum.py +0 -0
  349. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_field_map_validation.py +0 -0
  350. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
  351. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
  352. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_index_lookup.py +0 -0
  353. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_llm_recorder.py +0 -0
  354. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_loader.py +0 -0
  355. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_loader_bom.py +0 -0
  356. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_loader_class.py +0 -0
  357. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_merge.py +0 -0
  358. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_meta_attr.py +0 -0
  359. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_meta_data.py +0 -0
  360. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_meta_source.py +0 -0
  361. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_module_shortcuts.py +0 -0
  362. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_n2m_resolver.py +0 -0
  363. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_n2m_resolver_inherited.py +0 -0
  364. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
  365. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_one_primary_source.py +0 -0
  366. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_parser.py +0 -0
  367. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_parser_yaml.py +0 -0
  368. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_provider.py +0 -0
  369. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_provider_extension.py +0 -0
  370. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_registry.py +0 -0
  371. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_registry_completeness.py +0 -0
  372. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_registry_extend.py +0 -0
  373. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_registry_sealed.py +0 -0
  374. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_relationship_referential_actions.py +0 -0
  375. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_resolution_key.py +0 -0
  376. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
  377. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_serializer.py +0 -0
  378. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_shared_constants.py +0 -0
  379. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_smoke.py +0 -0
  380. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_sources.py +0 -0
  381. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_strict_child_placement.py +0 -0
  382. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_super_resolve.py +0 -0
  383. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_template_toolcall.py +0 -0
  384. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
  385. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_validation_attr_schema.py +0 -0
  386. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_validation_filter_values.py +0 -0
  387. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_validation_origin_paths.py +0 -0
  388. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_validation_sort_field.py +0 -0
  389. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_validation_warnings.py +0 -0
  390. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_write_coercion_arrays.py +0 -0
  391. {metaobjects-0.16.0 → metaobjects-0.18.0}/tests/unit/test_yaml_desugar.py +0 -0
  392. {metaobjects-0.16.0 → metaobjects-0.18.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metaobjects
3
- Version: 0.16.0
3
+ Version: 0.18.0
4
4
  Summary: Cross-language metadata standard: declare typed entities once, generate idiomatic drift-checked code across languages — Python port.
5
5
  Project-URL: Homepage, https://metaobjects.dev
6
6
  Project-URL: Repository, https://github.com/metaobjectsdev/metaobjects
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "metaobjects"
3
- version = "0.16.0"
3
+ version = "0.18.0"
4
4
  description = "Cross-language metadata standard: declare typed entities once, generate idiomatic drift-checked code across languages — Python port."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -14,7 +14,14 @@ from metaobjects.meta.core.identity.identity_constants import (
14
14
  IDENTITY_ATTR_GENERATION,
15
15
  )
16
16
  from metaobjects.meta.core.validator import validator_constants as vc
17
- from metaobjects.shared.base_types import TYPE_VALIDATOR
17
+ from metaobjects.meta.persistence.origin.origin_constants import (
18
+ AGG_ALL,
19
+ AGG_ANY,
20
+ AGG_COLLECT,
21
+ ORIGIN_ATTR_AGG,
22
+ ORIGIN_SUBTYPE_AGGREGATE,
23
+ )
24
+ from metaobjects.shared.base_types import TYPE_ORIGIN, TYPE_VALIDATOR
18
25
  from metaobjects.shared.separators import PACKAGE_SEP
19
26
  from metaobjects.codegen.config import GenConfig
20
27
  from metaobjects.codegen.constants import generated_header
@@ -221,6 +228,22 @@ def _type_expr_for_field(
221
228
  return type_expr, enum_type_name
222
229
 
223
230
 
231
+ def origin_guaranteed_non_null(field: MetaField) -> bool:
232
+ """#195 — a field derived by an origin.aggregate ``@agg:any|all|collect`` is
233
+ COALESCE-guaranteed non-null in the synthesized view (any→false, all→true,
234
+ collect→[]), so its read type is non-null even when the field is not ``@required``.
235
+ origin.first is deliberately NOT here — an empty related set selects no row (→ null);
236
+ origin.computed nullability is expression-dependent, so it stays the conservative
237
+ nullable default. Mirrors the TS originGuaranteedNonNull."""
238
+ # ADR-0039 sanctioned own — origin.* never inherits (ADR-0029), so own is correct.
239
+ for child in field.own_children():
240
+ if child.type == TYPE_ORIGIN and child.sub_type == ORIGIN_SUBTYPE_AGGREGATE:
241
+ agg = child.attr(ORIGIN_ATTR_AGG) # ADR-0039 own — origin attr
242
+ if agg in (AGG_ANY, AGG_ALL, AGG_COLLECT):
243
+ return True
244
+ return False
245
+
246
+
224
247
  def _field_line(field: MetaField, imports: set[str], config: GenConfig) -> tuple[str, bool]:
225
248
  """Return (source line, uses_field). Collects required imports into *imports*."""
226
249
  type_expr, enum_type_name = _type_expr_for_field(field, imports, config)
@@ -243,15 +266,20 @@ def _field_line(field: MetaField, imports: set[str], config: GenConfig) -> tuple
243
266
  else:
244
267
  default_expr = None
245
268
 
246
- # A field is Optional only when it is neither required nor carries a @default.
247
- annotation = type_expr if (required or has_default) else f"{type_expr} | None"
269
+ # #195 a field derived by an origin.aggregate any|all|collect always COALESCEs
270
+ # to a value (any→false, all→true, collect→[]), so its read type is mandatory
271
+ # non-null exactly like a @required field (no `| None`, no default). origin.first /
272
+ # origin.computed stay the conservative nullable default.
273
+ mandatory = required or origin_guaranteed_non_null(field)
274
+ # A field is Optional only when it is neither mandatory nor carries a @default.
275
+ annotation = type_expr if (mandatory or has_default) else f"{type_expr} | None"
248
276
  if has_default and uses_field:
249
277
  assignment = f" = Field(default={default_expr}, {', '.join(parts)})"
250
278
  elif has_default:
251
279
  assignment = f" = {default_expr}"
252
- elif required and uses_field:
280
+ elif mandatory and uses_field:
253
281
  assignment = f" = Field({', '.join(parts)})"
254
- elif required:
282
+ elif mandatory:
255
283
  assignment = ""
256
284
  elif uses_field:
257
285
  assignment = f" = Field(default=None, {', '.join(parts)})"
@@ -468,6 +496,8 @@ class EntityModelGenerator:
468
496
  continue # FR-036 #2 — a server-generated PK is never in the create body
469
497
  if f.attrs().get(fc.FIELD_ATTR_READ_ONLY) is True:
470
498
  continue # FR-013 — a read-only column is DB/owner-written, not create input
499
+ if f.is_derived():
500
+ continue # FR-024 §7 (#214) — a derived (origin.*) field is view-computed, not create input
471
501
  line, used = _create_field_line(f, imports, cfg)
472
502
  uses_field = uses_field or used
473
503
  lines.append(line)
@@ -501,6 +531,8 @@ class EntityModelGenerator:
501
531
  for f in entity.fields():
502
532
  if f.name in pk_fields:
503
533
  continue # FR-036 #4 — the PK is route-authoritative, never patched
534
+ if f.is_derived():
535
+ continue # FR-024 §7 (#214) — a derived (origin.*) field is view-computed, never patched
504
536
  line, used = _patch_field_line(f, imports, cfg)
505
537
  uses_field = uses_field or used
506
538
  lines.append(line)
@@ -250,7 +250,12 @@ class FilterAllowlistGenerator:
250
250
  src = _primary_source_rdb(entity)
251
251
  if src is None:
252
252
  return None
253
- if src.effective_kind() != SOURCE_KIND_TABLE:
253
+ # FR-024 §7 (#214): a write-through entity read-view is writable and its generated
254
+ # router imports this allowlist — so it MUST be emitted for write-through regardless of
255
+ # source declaration order (matching the router gate; else a view-source-first
256
+ # write-through router imports a never-generated module and FastAPI startup crashes). A
257
+ # projection (read-only source only) is not write-through, so it still skips.
258
+ if not entity.is_write_through() and src.effective_kind() != SOURCE_KIND_TABLE:
254
259
  return None
255
260
 
256
261
  short_name = entity.name
@@ -645,7 +645,12 @@ class RouterGenerator:
645
645
  src = _primary_source_rdb(entity)
646
646
  if src is None:
647
647
  return None
648
- if src.effective_kind() != SOURCE_KIND_TABLE:
648
+ # FR-024 §7 (#214): a write-through entity read-view is writable (owns a table
649
+ # source) and MUST emit its CRUD router regardless of source declaration order —
650
+ # the first-source gate below would wrongly skip a view-source-first write-through
651
+ # entity. Reads route to the replica view in the ObjectManager (not here). A
652
+ # projection (read-only source only) is not write-through, so it still skips.
653
+ if not entity.is_write_through() and src.effective_kind() != SOURCE_KIND_TABLE:
649
654
  return None
650
655
 
651
656
  # FR-017 TPH: a discriminator base emits a polymorphic collection at the base
@@ -6,6 +6,7 @@ from .attr_class_map import attr_class_for
6
6
  from .meta.core.attr import meta_attr as _attr # noqa: F401
7
7
  from .meta.core.attr.attr_constants import (
8
8
  ATTR_SUBTYPE_BOOLEAN,
9
+ ATTR_SUBTYPE_EXPRESSION,
9
10
  ATTR_SUBTYPE_FILTER,
10
11
  ATTR_SUBTYPE_INT,
11
12
  ATTR_SUBTYPE_STRING,
@@ -55,6 +56,7 @@ from .meta.core.object.meta_object import MetaObject
55
56
  from .meta.core.object.object_constants import (
56
57
  OBJECT_ATTR_DISCRIMINATOR,
57
58
  OBJECT_ATTR_DISCRIMINATOR_VALUE,
59
+ OBJECT_PROJECTION_ATTR_FILTER,
58
60
  OBJECT_SUBTYPE_ENTITY,
59
61
  OBJECT_SUBTYPE_PROJECTION,
60
62
  OBJECT_SUBTYPES,
@@ -77,12 +79,17 @@ from .meta.persistence.origin.meta_origin import MetaOrigin
77
79
  from .meta.persistence.origin.origin_constants import (
78
80
  ORIGIN_ATTR_AGG,
79
81
  ORIGIN_ATTR_CONVERT,
82
+ ORIGIN_ATTR_DISTINCT,
83
+ ORIGIN_ATTR_EXPR,
80
84
  ORIGIN_ATTR_FILTER,
81
85
  ORIGIN_ATTR_FROM,
82
86
  ORIGIN_ATTR_OF,
87
+ ORIGIN_ATTR_ORDER_BY,
83
88
  ORIGIN_ATTR_VIA,
84
89
  ORIGIN_SUBTYPE_AGGREGATE,
85
90
  ORIGIN_SUBTYPE_COLLECTION,
91
+ ORIGIN_SUBTYPE_COMPUTED,
92
+ ORIGIN_SUBTYPE_FIRST,
86
93
  ORIGIN_SUBTYPE_PASSTHROUGH,
87
94
  )
88
95
  from .meta.template.meta_template import MetaTemplate
@@ -96,7 +103,9 @@ from .meta.persistence.source.source_constants import (
96
103
  SOURCE_ATTR_PROC,
97
104
  SOURCE_ATTR_ROLE,
98
105
  SOURCE_ATTR_SCHEMA,
106
+ SOURCE_ATTR_SQL,
99
107
  SOURCE_ATTR_TABLE,
108
+ SOURCE_ATTR_UNMANAGED,
100
109
  SOURCE_ATTR_VIEW,
101
110
  SOURCE_RDB_KINDS,
102
111
  SOURCE_ROLES,
@@ -253,6 +262,26 @@ for _obj_sub in OBJECT_SUBTYPES:
253
262
  )
254
263
  )
255
264
 
265
+ # #207 — object.projection carries an optional row-scope @filter (a portable
266
+ # attr.filter object — the SAME attr subtype as origin.aggregate's @filter) that
267
+ # lowers to a view-level SQL WHERE. The object loop above registered every subtype
268
+ # with the shared discriminator attrs; append @filter to the projection def
269
+ # (mirrors the field.currency enrichment below, and the TS object provider, where
270
+ # object.json's projection block declares the filter attr child). The strict
271
+ # per-subtype attr scoping (apply_spec_descriptions) then keeps @filter on
272
+ # projection and prunes the shared discriminator attrs — object.json's projection
273
+ # block declares ONLY @filter.
274
+ for _def in core_provider._defs: # noqa: SLF001 (provider build-time enrichment)
275
+ if _def.type == TYPE_OBJECT and _def.sub_type == OBJECT_SUBTYPE_PROJECTION:
276
+ _def.attrs.append(
277
+ AttrSchema(
278
+ name=OBJECT_PROJECTION_ATTR_FILTER,
279
+ value_type=ATTR_SUBTYPE_FILTER,
280
+ required=False,
281
+ )
282
+ )
283
+ break
284
+
256
285
  # field.* (one factory, data_type by subtype)
257
286
  # Note: FIELD_SUBTYPE_ENUM is excluded from FIELD_SUBTYPES; it is registered
258
287
  # separately below with its required @values AttrSchema (sharing these child rules).
@@ -591,6 +620,9 @@ core_provider.add(
591
620
  allowed_values=SOURCE_ROLES,
592
621
  ),
593
622
  AttrSchema(name=SOURCE_ATTR_SCHEMA, value_type=ATTR_SUBTYPE_STRING, required=False),
623
+ # FR-024/#208 escape valves — registration only, no validation/lowering here.
624
+ AttrSchema(name=SOURCE_ATTR_SQL, value_type=ATTR_SUBTYPE_STRING, required=False),
625
+ AttrSchema(name=SOURCE_ATTR_UNMANAGED, value_type=ATTR_SUBTYPE_BOOLEAN, required=False),
594
626
  # FR-015 — @parameterRef: input-shape object.value for proc/table-function sources.
595
627
  AttrSchema(
596
628
  name=SOURCE_ATTR_PARAMETER_REF,
@@ -628,13 +660,13 @@ core_provider.add(
628
660
  )
629
661
  )
630
662
 
631
- # origin.aggregate — @agg + @of required; @agg has allowed values.
632
- # FR-024 (ADR-0029): @via flipped REQUIRED OPTIONAL it is inferable when
633
- # exactly one single-hop relationship reaches the @of entity (the inference
634
- # PASS itself is Phase-E validation parity). The cross-port manifest still
635
- # records the pre-flip required:true via the registry_manifest FR024_PENDING
636
- # required-override until the atomic all-ports manifest flip.
637
- _AGG_ALLOWED = ("count", "sum", "avg", "min", "max")
663
+ # origin.aggregate — @agg required; @of/@via/@distinct/@orderBy optional.
664
+ # FR-024 (ADR-0029): @via is inferable when exactly one single-hop relationship
665
+ # reaches the @of entity. #195: @of relaxed to optional (any/all forbid it, the
666
+ # rest require it) — presence is enforced per-@agg in the origin validation pass;
667
+ # @agg vocabulary extended with any/all (predicate quantifiers) + collect (array
668
+ # rollup); @distinct (collect set-semantics) + @orderBy (element/row ordering) added.
669
+ _AGG_ALLOWED = ("count", "sum", "avg", "min", "max", "any", "all", "collect")
638
670
  core_provider.add(
639
671
  TypeDefinition(
640
672
  type=TYPE_ORIGIN,
@@ -647,8 +679,41 @@ core_provider.add(
647
679
  required=True,
648
680
  allowed_values=_AGG_ALLOWED,
649
681
  ),
682
+ AttrSchema(name=ORIGIN_ATTR_OF, value_type=ATTR_SUBTYPE_STRING, required=False),
683
+ AttrSchema(name=ORIGIN_ATTR_VIA, value_type=ATTR_SUBTYPE_STRING, required=False),
684
+ AttrSchema(name=ORIGIN_ATTR_FILTER, value_type=ATTR_SUBTYPE_FILTER, required=False),
685
+ AttrSchema(name=ORIGIN_ATTR_DISTINCT, value_type=ATTR_SUBTYPE_BOOLEAN, required=False),
686
+ AttrSchema(name=ORIGIN_ATTR_ORDER_BY, value_type=ATTR_SUBTYPE_STRING, required=False, is_array=True),
687
+ ],
688
+ child_rules=[ChildRule(TYPE_ATTR, "*")],
689
+ )
690
+ )
691
+
692
+ # origin.computed (#195) — a row-level value from the base entity's own fields
693
+ # via a structured @expr tree (attr.expression). No related rows / @via.
694
+ core_provider.add(
695
+ TypeDefinition(
696
+ type=TYPE_ORIGIN,
697
+ sub_type=ORIGIN_SUBTYPE_COMPUTED,
698
+ factory=MetaOrigin,
699
+ attrs=[
700
+ AttrSchema(name=ORIGIN_ATTR_EXPR, value_type=ATTR_SUBTYPE_EXPRESSION, required=True),
701
+ ],
702
+ child_rules=[ChildRule(TYPE_ATTR, "*")],
703
+ )
704
+ )
705
+
706
+ # origin.first (#195) — the single related row selected by @orderBy along @via,
707
+ # projecting @of. @of + @orderBy required; @via + @filter optional.
708
+ core_provider.add(
709
+ TypeDefinition(
710
+ type=TYPE_ORIGIN,
711
+ sub_type=ORIGIN_SUBTYPE_FIRST,
712
+ factory=MetaOrigin,
713
+ attrs=[
650
714
  AttrSchema(name=ORIGIN_ATTR_OF, value_type=ATTR_SUBTYPE_STRING, required=True),
651
715
  AttrSchema(name=ORIGIN_ATTR_VIA, value_type=ATTR_SUBTYPE_STRING, required=False),
716
+ AttrSchema(name=ORIGIN_ATTR_ORDER_BY, value_type=ATTR_SUBTYPE_STRING, required=True, is_array=True),
652
717
  AttrSchema(name=ORIGIN_ATTR_FILTER, value_type=ATTR_SUBTYPE_FILTER, required=False),
653
718
  ],
654
719
  child_rules=[ChildRule(TYPE_ATTR, "*")],
@@ -60,6 +60,13 @@ class ErrorCode(str, Enum):
60
60
  # is to-one at every hop (you meant passthrough).
61
61
  ERR_AMBIGUOUS_PATH = "ERR_AMBIGUOUS_PATH"
62
62
  ERR_ORIGIN_CARDINALITY = "ERR_ORIGIN_CARDINALITY"
63
+ # #195 — origin.computed @expr validation. ERR_UNKNOWN_EXPR_NODE: the expression
64
+ # tree contains a node whose kind/op/fn is not in the closed grammar (fail-closed
65
+ # per ADR-0023). ERR_COMPUTED_TYPE_MISMATCH: the @expr tree's inferred root type
66
+ # does not equal the carrying field's declared field.<subType> (a computed column's
67
+ # type is DERIVED from its expression, never asserted — no @convert escape).
68
+ ERR_UNKNOWN_EXPR_NODE = "ERR_UNKNOWN_EXPR_NODE"
69
+ ERR_COMPUTED_TYPE_MISMATCH = "ERR_COMPUTED_TYPE_MISMATCH"
63
70
  # FR-024 B6 — extends/origin agreement + derived-field providability. Vocabulary-
64
71
  # only here until FR-024 Phase E (the Python loader does not run these checks yet):
65
72
  # ERR_EXTENDS_ORIGIN_MISMATCH — a field's entity-nested extends (shape lineage)
@@ -156,6 +163,20 @@ class ErrorCode(str, Enum):
156
163
  # the validate()-time structural enforcement is the next sub-step).
157
164
  ERR_CHILD_NOT_ALLOWED = "ERR_CHILD_NOT_ALLOWED"
158
165
  ERR_INVALID_METAMODEL_CONSTRAINT = "ERR_INVALID_METAMODEL_CONSTRAINT"
166
+ # #208 — DDL-ownership escape valves (source.rdb @sql / @unmanaged).
167
+ # ERR_SQL_BODY_WITH_UNMANAGED: @sql AND @unmanaged declared on the SAME
168
+ # source — the two mutually exclusive non-default DDL-ownership states.
169
+ # ERR_SQL_BODY_ON_WRITABLE_KIND: @sql set on a writable @kind ("table", the
170
+ # default) — @sql is legal only on a read-only kind; a writable table is
171
+ # either fully modeled or @unmanaged, never opaque-bodied.
172
+ # ERR_ORIGIN_UNDER_SQL_BODY: an origin.*-bearing (derived) own field, or an
173
+ # object.projection @filter (#207), under an @sql host — two sources of
174
+ # truth for the same body. (R6's WARN_ORIGIN_UNDER_UNMANAGED sibling — an
175
+ # origin.*-bearing field under an @unmanaged host — is a warning, not an
176
+ # error code; it lives in the envelope-warnings channel.)
177
+ ERR_SQL_BODY_WITH_UNMANAGED = "ERR_SQL_BODY_WITH_UNMANAGED"
178
+ ERR_SQL_BODY_ON_WRITABLE_KIND = "ERR_SQL_BODY_ON_WRITABLE_KIND"
179
+ ERR_ORIGIN_UNDER_SQL_BODY = "ERR_ORIGIN_UNDER_SQL_BODY"
159
180
  ERR_UNKNOWN = "ERR_UNKNOWN"
160
181
 
161
182
 
@@ -0,0 +1,205 @@
1
+ """#208 — DDL-ownership escape valves loader validation (source.rdb @sql / @unmanaged).
2
+
3
+ Sibling of validate_source_parameter_ref.py / validate_source_physical_names.py.
4
+
5
+ #208 gives source.rdb two mutually exclusive, non-default DDL-ownership
6
+ markers: ``@sql`` (a hand-written body the tool registers/fingerprints/drift-
7
+ checks but never authors) and ``@unmanaged`` (this object's DDL is owned
8
+ elsewhere — the tool never touches it). This pass enforces the six
9
+ fail-closed rules from the design doc (§5):
10
+
11
+ R1 @sql AND @unmanaged on the SAME source -> ERR_SQL_BODY_WITH_UNMANAGED
12
+ R2 @sql on a writable @kind ("table", the default) -> ERR_SQL_BODY_ON_WRITABLE_KIND
13
+ R3 @sql present but empty / whitespace-only -> ERR_BAD_ATTR_VALUE
14
+ R4 origin.*-bearing field under an @sql host -> ERR_ORIGIN_UNDER_SQL_BODY
15
+ R5 object.projection @filter (#207) + @sql host -> ERR_ORIGIN_UNDER_SQL_BODY
16
+ R6 origin.*-bearing field under an @unmanaged host -> WARN_ORIGIN_UNDER_UNMANAGED
17
+
18
+ R1-R3 are per-source (declaration-layer). R4-R6 are per-host-object: a host
19
+ with ANY own source.rdb carrying @sql/@unmanaged is judged against its own
20
+ fields (and, for R5, its own @filter). The asymmetry between R4 (hard error)
21
+ and R6 (warn) is deliberate (design doc §5.6): @sql is a second body (two
22
+ sources of truth for the SAME data); @unmanaged acts on nothing, so a
23
+ documented-but-unacted-on lineage is benign.
24
+
25
+ Mirrors the TS reference
26
+ ``packages/typescript/packages/metadata/src/persistence/source/validate-source-escapes.ts``.
27
+ """
28
+ from __future__ import annotations
29
+
30
+ from ..errors import ErrorCode, MetaError
31
+ from ..meta.core.field.meta_field import MetaField
32
+ from ..meta.core.object.object_constants import (
33
+ OBJECT_PROJECTION_ATTR_FILTER,
34
+ OBJECT_SUBTYPE_PROJECTION,
35
+ )
36
+ from ..meta.meta_data import MetaData
37
+ from ..meta.persistence.source.meta_source import MetaSource
38
+ from ..meta.persistence.source.source_constants import (
39
+ SOURCE_ATTR_SQL,
40
+ SOURCE_SUBTYPE_RDB,
41
+ )
42
+ from ..shared.base_types import TYPE_FIELD, TYPE_OBJECT, TYPE_SOURCE
43
+ from ..source.error_source import LoaderWarning
44
+
45
+ WARN_ORIGIN_UNDER_UNMANAGED = "WARN_ORIGIN_UNDER_UNMANAGED"
46
+
47
+
48
+ def validate_source_escapes(
49
+ root: MetaData,
50
+ errors: list[MetaError],
51
+ envelope_warnings: list[LoaderWarning] | None = None,
52
+ legacy_warnings: list[str] | None = None,
53
+ ) -> None:
54
+ """Run the #208 R1-R6 @sql / @unmanaged DDL-ownership validation.
55
+
56
+ ``envelope_warnings`` collects the FR5c-style envelope warning
57
+ (``WARN_ORIGIN_UNDER_UNMANAGED``, R6). ``legacy_warnings`` mirrors the
58
+ cross-port string warnings channel — populated with the same code string
59
+ so the legacy ``warnings: list[str]`` consumers see something too.
60
+ """
61
+ # ADR-0039 sanctioned own: root has no super (children()==own_children()),
62
+ # and every object is declared at the root level (mirrors the TS
63
+ # reference's root.children() walk).
64
+ for obj in root.own_children():
65
+ if obj.type != TYPE_OBJECT:
66
+ continue
67
+
68
+ # ADR-0039 sanctioned own: declaration-layer source iteration (mirrors
69
+ # validate_source_parameter_ref / _validate_one_primary_source):
70
+ # R1-R3 judge markers DECLARED on this object's own sources.
71
+ sources = [
72
+ c
73
+ for c in obj.own_children()
74
+ if c.type == TYPE_SOURCE
75
+ and c.sub_type == SOURCE_SUBTYPE_RDB
76
+ and isinstance(c, MetaSource)
77
+ ]
78
+
79
+ has_sql_host = False
80
+ has_unmanaged_host = False
81
+
82
+ for source in sources:
83
+ # ADR-0039: resolving — @sql/@unmanaged are inheritable (follow
84
+ # the @role/effective_kind precedent — sources are inheritable,
85
+ # NOT the @dbColumnType own-only exception).
86
+ sql_set = source.sql_body() is not None
87
+ unmanaged_set = source.is_unmanaged()
88
+
89
+ # R1 — contradictory DDL owners on the same source.
90
+ if sql_set and unmanaged_set:
91
+ errors.append(
92
+ MetaError(
93
+ f'source.rdb on object "{obj.name}" declares both @sql and '
94
+ "@unmanaged — these are the mutually exclusive non-default "
95
+ "states of one DDL-ownership axis (an author-supplied body "
96
+ 'contradicts "someone else owns this DDL")',
97
+ ErrorCode.ERR_SQL_BODY_WITH_UNMANAGED,
98
+ envelope=source.source,
99
+ )
100
+ )
101
+
102
+ # R2 — @sql on a writable kind would bypass the column-diff
103
+ # machinery; tables are fully modeled or @unmanaged, never
104
+ # opaque-bodied.
105
+ if sql_set and source.is_writable():
106
+ errors.append(
107
+ MetaError(
108
+ f'source.rdb on object "{obj.name}" declares @sql with a '
109
+ f'writable @kind ("{source.effective_kind()}") — @sql is '
110
+ "legal only on a read-only kind (view/materializedView/"
111
+ "storedProc/tableFunction); a writable table is either "
112
+ "fully modeled or marked @unmanaged, never opaque-bodied",
113
+ ErrorCode.ERR_SQL_BODY_ON_WRITABLE_KIND,
114
+ envelope=source.source,
115
+ )
116
+ )
117
+
118
+ # R3 — @sql present but empty/whitespace. MUST read the raw attr,
119
+ # not the sql_body() accessor: sql_body() already narrows an
120
+ # empty string to None, which would make a present-but-empty
121
+ # @sql indistinguishable from an absent one.
122
+ raw_sql = source.get_meta_attr(SOURCE_ATTR_SQL)
123
+ if raw_sql is not None and (
124
+ not isinstance(raw_sql, str) or raw_sql.strip() == ""
125
+ ):
126
+ errors.append(
127
+ MetaError(
128
+ f'source.rdb on object "{obj.name}" sets @sql to an '
129
+ "empty/whitespace-only value; @sql requires a non-empty "
130
+ "SQL body",
131
+ ErrorCode.ERR_BAD_ATTR_VALUE,
132
+ envelope=source.source,
133
+ )
134
+ )
135
+
136
+ if sql_set:
137
+ has_sql_host = True
138
+ if unmanaged_set:
139
+ has_unmanaged_host = True
140
+
141
+ if not has_sql_host and not has_unmanaged_host:
142
+ continue
143
+
144
+ # R4 / R6 — origin.*-bearing (derived) own fields under an @sql /
145
+ # @unmanaged host. ADR-0039: own — origin.* never inherits
146
+ # (ADR-0029), so is_derived() is own-only by policy (mirrors
147
+ # _validate_derived_field_providability). @sql (hard error) takes
148
+ # priority over @unmanaged (warn) when a host happens to declare
149
+ # both markers across different sources.
150
+ for child in obj.own_children():
151
+ if child.type != TYPE_FIELD or not isinstance(child, MetaField):
152
+ continue
153
+ if not child.is_derived():
154
+ continue
155
+ if has_sql_host:
156
+ errors.append(
157
+ MetaError(
158
+ f'field "{obj.name}.{child.name}" carries an origin.* '
159
+ f'(derived) child, but "{obj.name}" has a read source '
160
+ "carrying @sql — the synthesized derivation and the "
161
+ "author's verbatim SQL are two sources of truth for the "
162
+ "same body",
163
+ ErrorCode.ERR_ORIGIN_UNDER_SQL_BODY,
164
+ envelope=child.source,
165
+ )
166
+ )
167
+ else:
168
+ msg = (
169
+ f'field "{obj.name}.{child.name}" carries an origin.* '
170
+ f'(derived) child, but "{obj.name}" has a source marked '
171
+ "@unmanaged — the tool never touches this object's DDL, so "
172
+ "the derivation is documented lineage only (not acted on); "
173
+ "this is informational, not an error"
174
+ )
175
+ if envelope_warnings is not None:
176
+ envelope_warnings.append(
177
+ LoaderWarning(
178
+ code=WARN_ORIGIN_UNDER_UNMANAGED,
179
+ message=msg,
180
+ source=child.source,
181
+ )
182
+ )
183
+ if legacy_warnings is not None:
184
+ legacy_warnings.append(WARN_ORIGIN_UNDER_UNMANAGED)
185
+
186
+ # R5 — a projection's row-scope @filter (#207) lowers to the outer
187
+ # WHERE of a TOOL-SYNTHESIZED body; with @sql the author owns the
188
+ # body (and its WHERE), so wrapping it is deferred cleverness
189
+ # (design doc D5) — reject.
190
+ if has_sql_host and obj.sub_type == OBJECT_SUBTYPE_PROJECTION:
191
+ # ADR-0039: own — the @filter is declared locally on this
192
+ # projection (mirrors _validate_projection_filter).
193
+ filter_value = obj.attr(OBJECT_PROJECTION_ATTR_FILTER)
194
+ if filter_value is not None:
195
+ errors.append(
196
+ MetaError(
197
+ f'projection "{obj.name}" declares both @filter and an '
198
+ "@sql read source — a view-level @filter lowers to the "
199
+ "outer WHERE of a synthesized body; with @sql the author "
200
+ "owns the body (and its WHERE), so the two cannot be "
201
+ "combined",
202
+ ErrorCode.ERR_ORIGIN_UNDER_SQL_BODY,
203
+ envelope=obj.source,
204
+ )
205
+ )