metaobjects 1.0.3__tar.gz → 1.0.4__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 (455) hide show
  1. {metaobjects-1.0.3 → metaobjects-1.0.4}/PKG-INFO +1 -1
  2. {metaobjects-1.0.3 → metaobjects-1.0.4}/pyproject.toml +1 -1
  3. {metaobjects-1.0.3 → metaobjects-1.0.4}/scripts/generate_embedded_library.py +36 -3
  4. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/cli.py +99 -25
  5. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/constants.py +11 -2
  6. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generator_registry.py +38 -5
  7. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/router_generator.py +12 -8
  8. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/trace_helper_generator.py +31 -10
  9. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/config/dependencies.py +82 -0
  10. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/errors.py +9 -0
  11. metaobjects-1.0.4/src/metaobjects/library/embedded_library.py +22 -0
  12. metaobjects-1.0.4/src/metaobjects/library/library_sources.py +191 -0
  13. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/merge.py +17 -2
  14. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validation_passes.py +186 -24
  15. metaobjects-1.0.4/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +347 -0
  16. metaobjects-1.0.4/src/metaobjects/meta/core/relationship/relationship_references.py +166 -0
  17. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/meta_data.py +6 -0
  18. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/naming_refs.py +11 -0
  19. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/relationship.json +8 -8
  20. metaobjects-1.0.4/tests/codegen/gen_suite.py +16 -0
  21. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/extends/expected/BaseEntity.py +1 -1
  22. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/extends/expected/Program.py +1 -1
  23. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +1 -1
  24. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/nested-array/expected/PostBrief.py +1 -1
  25. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/scalars/expected/Metric.py +1 -1
  26. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/scalars/expected/Report.py +1 -1
  27. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/vanilla/expected/Subscriber.py +1 -1
  28. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli.py +43 -42
  29. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_config_gen.py +11 -10
  30. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_config_verify.py +35 -34
  31. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_dependencies.py +11 -10
  32. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_providers.py +7 -5
  33. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_registry.py +3 -2
  34. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_staleness_nudge.py +6 -5
  35. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_verify_strict.py +8 -7
  36. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_verify_subverbs.py +21 -20
  37. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_gen_state_keying.py +3 -2
  38. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_m2m_codegen.py +41 -0
  39. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_names_generator.py +7 -6
  40. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_reverse_finders.py +89 -0
  41. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_trace_helper_generator.py +47 -4
  42. metaobjects-1.0.4/tests/config/test_library_package_guard.py +112 -0
  43. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_generator_registry_conformance.py +31 -1
  44. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_llm_call_trace.py +3 -2
  45. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_shipped_library_ai.py +13 -2
  46. metaobjects-1.0.4/tests/unit/test_derive_m2m_declaring_entity.py +358 -0
  47. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_llm_recorder.py +6 -3
  48. metaobjects-1.0.4/tests/unit/test_relationship_m2m_validation.py +557 -0
  49. metaobjects-1.0.4/tests/unit/test_relationship_references.py +203 -0
  50. {metaobjects-1.0.3 → metaobjects-1.0.4}/uv.lock +1 -1
  51. metaobjects-1.0.3/src/metaobjects/library/embedded_library.py +0 -11
  52. metaobjects-1.0.3/src/metaobjects/library/library_sources.py +0 -99
  53. metaobjects-1.0.3/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -185
  54. {metaobjects-1.0.3 → metaobjects-1.0.4}/.gitignore +0 -0
  55. {metaobjects-1.0.3 → metaobjects-1.0.4}/LICENSE +0 -0
  56. {metaobjects-1.0.3 → metaobjects-1.0.4}/README.md +0 -0
  57. {metaobjects-1.0.3 → metaobjects-1.0.4}/hatch_build.py +0 -0
  58. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/__init__.py +0 -0
  59. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/agent_context/__init__.py +0 -0
  60. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/agent_context/scaffold.py +0 -0
  61. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/__init__.py +0 -0
  62. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/api_model.py +0 -0
  63. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/builder.py +0 -0
  64. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/naming.py +0 -0
  65. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/paths.py +0 -0
  66. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/renderer.py +0 -0
  67. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/attr_class_map.py +0 -0
  68. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
  69. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/__init__.py +0 -0
  70. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/collision_names.py +0 -0
  71. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/config.py +0 -0
  72. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
  73. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
  74. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/format.py +0 -0
  75. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
  76. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generator.py +0 -0
  77. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/__init__.py +0 -0
  78. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/entity_model.py +0 -0
  79. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
  80. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
  81. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/find_inbound.py +0 -0
  82. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
  83. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
  84. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/names_generator.py +0 -0
  85. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
  86. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
  87. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/payload_vo_generator.py +0 -0
  88. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
  89. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/template_generator.py +0 -0
  90. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
  91. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/instance_artifacts.py +0 -0
  92. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/metaobjects-config.schema.json +0 -0
  93. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
  94. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/overwrite_policy.py +0 -0
  95. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/project_config.py +0 -0
  96. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/runner.py +0 -0
  97. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/runtime/__init__.py +0 -0
  98. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
  99. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
  100. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
  101. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
  102. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
  103. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/type_map.py +0 -0
  104. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/config/__init__.py +0 -0
  105. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/config/neutral_config.py +0 -0
  106. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/config/source_resolver.py +0 -0
  107. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/core_types.py +0 -0
  108. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/datatype.py +0 -0
  109. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/documentation/__init__.py +0 -0
  110. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/documentation/doc_constants.py +0 -0
  111. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/documentation/doc_provider.py +0 -0
  112. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/documentation/doc_schema.py +0 -0
  113. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/library/__init__.py +0 -0
  114. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/__init__.py +0 -0
  115. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/meta_data_loader.py +0 -0
  116. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/registered_validation.py +0 -0
  117. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/__init__.py +0 -0
  118. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/directory_source.py +0 -0
  119. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/file_source.py +0 -0
  120. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
  121. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/uri_source.py +0 -0
  122. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_discriminator.py +0 -0
  123. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_enum_normalize_ambiguity.py +0 -0
  124. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_field_mutability.py +0 -0
  125. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_source_escapes.py +0 -0
  126. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
  127. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
  128. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/__init__.py +0 -0
  129. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/__init__.py +0 -0
  130. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/attr/__init__.py +0 -0
  131. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
  132. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
  133. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/field/__init__.py +0 -0
  134. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/field/field_constants.py +0 -0
  135. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/field/meta_field.py +0 -0
  136. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/identity/__init__.py +0 -0
  137. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
  138. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
  139. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/index/__init__.py +0 -0
  140. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/index/index_constants.py +0 -0
  141. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/index/meta_index.py +0 -0
  142. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/__init__.py +0 -0
  143. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/meta_object.py +0 -0
  144. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
  145. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
  146. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/object_constants.py +0 -0
  147. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/object_extract.py +0 -0
  148. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/value_object.py +0 -0
  149. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
  150. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
  151. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
  152. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/requirement/__init__.py +0 -0
  153. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/requirement/meta_requirement.py +0 -0
  154. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/requirement/requirement_constants.py +0 -0
  155. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/validator/__init__.py +0 -0
  156. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
  157. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/meta_root.py +0 -0
  158. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/__init__.py +0 -0
  159. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
  160. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
  161. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
  162. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
  163. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
  164. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
  165. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
  166. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
  167. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
  168. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/__init__.py +0 -0
  169. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
  170. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
  171. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
  172. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
  173. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
  174. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
  175. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
  176. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
  177. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/provider_extends.py +0 -0
  178. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/template/__init__.py +0 -0
  179. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/template/meta_template.py +0 -0
  180. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/template/prompt_provider.py +0 -0
  181. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/template/template_constants.py +0 -0
  182. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/naming.py +0 -0
  183. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/parser.py +0 -0
  184. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/parser_yaml.py +0 -0
  185. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/provider.py +0 -0
  186. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/py.typed +0 -0
  187. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/registry.py +0 -0
  188. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/registry_manifest.py +0 -0
  189. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/__init__.py +0 -0
  190. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/email_document.py +0 -0
  191. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/escapers.py +0 -0
  192. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
  193. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/__init__.py +0 -0
  194. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/coerce.py +0 -0
  195. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/extract.py +0 -0
  196. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/extract_map.py +0 -0
  197. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
  198. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/locate.py +0 -0
  199. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/normalize.py +0 -0
  200. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/strip.py +0 -0
  201. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/types.py +0 -0
  202. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
  203. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/filesystem_provider.py +0 -0
  204. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/payload_accessors.py +0 -0
  205. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/__init__.py +0 -0
  206. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
  207. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
  208. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/prompt_field.py +0 -0
  209. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
  210. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/prompt_style.py +0 -0
  211. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/renderer.py +0 -0
  212. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/verify.py +0 -0
  213. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/__init__.py +0 -0
  214. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/llm_recorder.py +0 -0
  215. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/n2m_resolver.py +0 -0
  216. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/object_manager.py +0 -0
  217. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/tph.py +0 -0
  218. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/scope.py +0 -0
  219. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/serializer_json.py +0 -0
  220. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/shared/__init__.py +0 -0
  221. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/shared/base_types.py +0 -0
  222. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/shared/separators.py +0 -0
  223. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/shared/structural.py +0 -0
  224. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/__init__.py +0 -0
  225. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/error_source.py +0 -0
  226. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/json_path.py +0 -0
  227. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/semantic_diff.py +0 -0
  228. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/yaml_positions.py +0 -0
  229. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source_resolution.py +0 -0
  230. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/__init__.py +0 -0
  231. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/attr.json +0 -0
  232. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/db.json +0 -0
  233. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/documentation.json +0 -0
  234. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/field.json +0 -0
  235. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/identity.json +0 -0
  236. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/index.json +0 -0
  237. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/layout.json +0 -0
  238. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/object.json +0 -0
  239. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/origin.json +0 -0
  240. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/prompt.json +0 -0
  241. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/requirement.json +0 -0
  242. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/source.json +0 -0
  243. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/template.json +0 -0
  244. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
  245. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/ui.json +0 -0
  246. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/validator.json +0 -0
  247. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/view.json +0 -0
  248. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/super_resolve.py +0 -0
  249. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/validation_types.py +0 -0
  250. {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/yaml_desugar.py +0 -0
  251. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/__init__.py +0 -0
  252. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/__init__.py +0 -0
  253. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/extends/meta.json +0 -0
  254. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/nested-array/meta.json +0 -0
  255. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/scalars/meta.json +0 -0
  256. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/vanilla/meta.json +0 -0
  257. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_abstract_conformance.py +0 -0
  258. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_api_docs_builder.py +0 -0
  259. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_api_docs_paths.py +0 -0
  260. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_constants_config.py +0 -0
  261. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_entity_model.py +0 -0
  262. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_enum_conformance.py +0 -0
  263. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
  264. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_extract_tier_collision.py +0 -0
  265. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_extractor_generator.py +0 -0
  266. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_filter_allowlist_generator.py +0 -0
  267. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_format.py +0 -0
  268. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
  269. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_fr010_output_codegen.py +0 -0
  270. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
  271. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_generator.py +0 -0
  272. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_generator_extension_seams.py +0 -0
  273. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_golden.py +0 -0
  274. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
  275. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_inheritance_conformance.py +0 -0
  276. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_instance_artifacts.py +0 -0
  277. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_names_extends_chain.py +0 -0
  278. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_no_magic_physical_names.py +0 -0
  279. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_origin_nullability.py +0 -0
  280. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_output_parser_generator.py +0 -0
  281. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_overwrite_policy.py +0 -0
  282. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_overwrite_policy_hash.py +0 -0
  283. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_payload_vo_generator.py +0 -0
  284. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_project_config.py +0 -0
  285. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_projection_compile.py +0 -0
  286. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_render_helper_conformance.py +0 -0
  287. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_render_helper_generator.py +0 -0
  288. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_router_autoset.py +0 -0
  289. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_router_generator.py +0 -0
  290. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_runner.py +0 -0
  291. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_source_resolution.py +0 -0
  292. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_sourceless_projection.py +0 -0
  293. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_data.py +0 -0
  294. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_generator.py +0 -0
  295. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_output_pattern.py +0 -0
  296. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_scope_helpers.py +0 -0
  297. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_scope_walk.py +0 -0
  298. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_spec.py +0 -0
  299. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_tph_codegen.py +0 -0
  300. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_type_map.py +0 -0
  301. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_validation_conformance.py +0 -0
  302. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_write_through.py +0 -0
  303. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/config/__init__.py +0 -0
  304. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/config/test_dependencies.py +0 -0
  305. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/config/test_neutral_config.py +0 -0
  306. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/config/test_source_resolver.py +0 -0
  307. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/__init__.py +0 -0
  308. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/capabilities.py +0 -0
  309. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/conformance-expected-failures.json +0 -0
  310. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/conformance_adapter.py +0 -0
  311. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/corpus.py +0 -0
  312. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/expected_failures.py +0 -0
  313. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/fixture_discovery.py +0 -0
  314. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/navigator.py +0 -0
  315. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
  316. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_conformance.py +0 -0
  317. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_dependency_conformance.py +0 -0
  318. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_extract_conformance.py +0 -0
  319. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_extract_object_verdict.py +0 -0
  320. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_fr010_loader_attrs.py +0 -0
  321. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_fr011_attrs.py +0 -0
  322. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_object_model_conformance.py +0 -0
  323. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_provider_composition_conformance.py +0 -0
  324. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_registry_conformance.py +0 -0
  325. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_runner_hardfail.py +0 -0
  326. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_scope_conformance.py +0 -0
  327. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_source_resolution_conformance.py +0 -0
  328. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_spec_metamodel_embed.py +0 -0
  329. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_strict_attr_load.py +0 -0
  330. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_template_codegen_conformance.py +0 -0
  331. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_template_generator_conformance.py +0 -0
  332. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_yaml_conformance.py +0 -0
  333. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
  334. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/__init__.py +0 -0
  335. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/api_contract_assertions.py +0 -0
  336. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/api_contract_jsonb_server.py +0 -0
  337. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/api_contract_m2m_server.py +0 -0
  338. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/api_contract_server.py +0 -0
  339. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/generated_jsonb_app.py +0 -0
  340. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/generated_m2m_app.py +0 -0
  341. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/generated_router_app.py +0 -0
  342. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/generated_tph_app.py +0 -0
  343. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/meta_ai_trace.yaml +0 -0
  344. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/normalization.py +0 -0
  345. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/postgres_container.py +0 -0
  346. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/query_runner.py +0 -0
  347. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/scenarios.py +0 -0
  348. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract.py +0 -0
  349. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_generated.py +0 -0
  350. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_jsonb.py +0 -0
  351. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_m2m.py +0 -0
  352. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_m2m_generated.py +0 -0
  353. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_tph_generated.py +0 -0
  354. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_generated_router_uuid_pk.py +0 -0
  355. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_normalization.py +0 -0
  356. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_query_scenarios.py +0 -0
  357. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_runtime_return_types.py +0 -0
  358. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/__init__.py +0 -0
  359. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_abstract_subtype_authored.py +0 -0
  360. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_enum_extends_values_conflict.py +0 -0
  361. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_field_mutability_order.py +0 -0
  362. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_template_payload_target_210.py +0 -0
  363. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/open_closed_proof_test.py +0 -0
  364. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/__init__.py +0 -0
  365. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/__init__.py +0 -0
  366. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_coerce.py +0 -0
  367. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_extract.py +0 -0
  368. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_extract_map.py +0 -0
  369. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_json_forgiving_reader.py +0 -0
  370. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_locate.py +0 -0
  371. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_model.py +0 -0
  372. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_normalize.py +0 -0
  373. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_strip.py +0 -0
  374. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
  375. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/prompt/__init__.py +0 -0
  376. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/prompt/test_output_format_renderer.py +0 -0
  377. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_email_document.py +0 -0
  378. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_filesystem_provider.py +0 -0
  379. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_output_format_renderer_nested.py +0 -0
  380. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_output_prompt_conformance.py +0 -0
  381. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_render_conformance.py +0 -0
  382. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_render_max_chars.py +0 -0
  383. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_verify.py +0 -0
  384. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_verify_conformance.py +0 -0
  385. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/runtime/test_object_manager_enum_intvaluemap.py +0 -0
  386. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/runtime/test_object_manager_table_name.py +0 -0
  387. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/__init__.py +0 -0
  388. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_fr5c_merge_attribution.py +0 -0
  389. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_fr5d_reference_resolution.py +0 -0
  390. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_fr5e_database_source_shape.py +0 -0
  391. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_json_path.py +0 -0
  392. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_semantic_diff.py +0 -0
  393. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_source_on_node.py +0 -0
  394. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_yaml_positions.py +0 -0
  395. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/test_api_docs_accuracy.py +0 -0
  396. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/__init__.py +0 -0
  397. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_agent_context_staleness.py +0 -0
  398. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_capabilities.py +0 -0
  399. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_column_naming_strategy.py +0 -0
  400. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_common_attrs.py +0 -0
  401. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_core_types.py +0 -0
  402. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_effective_children_sibling_shadowing.py +0 -0
  403. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_effective_package.py +0 -0
  404. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_errors.py +0 -0
  405. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_field_enum.py +0 -0
  406. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_field_enum_intvaluemap.py +0 -0
  407. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_field_map_validation.py +0 -0
  408. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
  409. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_file_source_id.py +0 -0
  410. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
  411. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_index_lookup.py +0 -0
  412. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_loader.py +0 -0
  413. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_loader_bom.py +0 -0
  414. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_loader_class.py +0 -0
  415. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_merge.py +0 -0
  416. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_meta_attr.py +0 -0
  417. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_meta_data.py +0 -0
  418. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_meta_source.py +0 -0
  419. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_module_shortcuts.py +0 -0
  420. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_n2m_resolver.py +0 -0
  421. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_n2m_resolver_inherited.py +0 -0
  422. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_no_dead_config_fields.py +0 -0
  423. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
  424. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
  425. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_object_manager_write_through.py +0 -0
  426. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_one_primary_source.py +0 -0
  427. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_parser.py +0 -0
  428. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_parser_yaml.py +0 -0
  429. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_provider.py +0 -0
  430. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_provider_extension.py +0 -0
  431. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_registry.py +0 -0
  432. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_registry_completeness.py +0 -0
  433. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_registry_extend.py +0 -0
  434. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_registry_sealed.py +0 -0
  435. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_relationship_referential_actions.py +0 -0
  436. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_resolution_key.py +0 -0
  437. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
  438. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_serializer.py +0 -0
  439. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_serializer_shared_document.py +0 -0
  440. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_shared_constants.py +0 -0
  441. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_smoke.py +0 -0
  442. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_source_escapes.py +0 -0
  443. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_sources.py +0 -0
  444. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_strict_child_placement.py +0 -0
  445. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_super_resolve.py +0 -0
  446. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_template_toolcall.py +0 -0
  447. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
  448. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_attr_schema.py +0 -0
  449. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_filter_values.py +0 -0
  450. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_origin_195.py +0 -0
  451. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_origin_paths.py +0 -0
  452. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_sort_field.py +0 -0
  453. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_warnings.py +0 -0
  454. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_write_coercion_arrays.py +0 -0
  455. {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_yaml_desugar.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: metaobjects
3
- Version: 1.0.3
3
+ Version: 1.0.4
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 = "1.0.3"
3
+ version = "1.0.4"
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"
@@ -52,10 +52,43 @@ def main() -> int:
52
52
  if not entries:
53
53
  raise SystemExit(f"no *.yaml found under {library_dir} — refusing to emit an empty library")
54
54
 
55
- body = "".join(f" {ref!r}: {text!r},\n" for ref, text in entries)
56
- out_path.write_text(HEADER + body + "}\n", encoding="utf-8")
55
+ # The MANIFESTS ride the same embed, in their own map keyed by library NAME.
56
+ #
57
+ # Their own map rather than another entry in the ref map, because a ref is
58
+ # "path under library/ minus .yaml" and every reader appends ``.yaml`` back. Folding
59
+ # a ``.json`` into that would mean a special case at every call site in four ports.
60
+ manifests = []
61
+ missing = []
62
+ for d in sorted(p for p in library_dir.iterdir() if p.is_dir()):
63
+ manifest = d / "library.json"
64
+ if manifest.is_file():
65
+ manifests.append((d.name, manifest.read_text(encoding="utf-8")))
66
+ else:
67
+ missing.append(d.name)
68
+
69
+ # A library directory with no manifest is a build error, not a silently-skipped one:
70
+ # the manifest declares the library's LAYERS, and without it ``libraries: ["iam/db"]``
71
+ # resolves to nothing and the adopter gets an empty tree with no explanation.
72
+ if missing:
73
+ raise SystemExit(f"library director{'y' if len(missing) == 1 else 'ies'} with no library.json: {', '.join(missing)}")
57
74
 
58
- print(f"wrote {out_path.relative_to(root)} ({len(entries)} ref(s): {', '.join(r for r, _ in entries)})")
75
+ body = "".join(f" {ref!r}: {text!r},\n" for ref, text in entries)
76
+ manifest_body = "".join(f" {name!r}: {text!r},\n" for name, text in manifests)
77
+ out_path.write_text(
78
+ HEADER
79
+ + body
80
+ + "}\n\n"
81
+ + "#: Library NAME -> the exact text of its ``library.json`` manifest.\n"
82
+ + "EMBEDDED_LIBRARY_MANIFESTS: dict[str, str] = {\n"
83
+ + manifest_body
84
+ + "}\n",
85
+ encoding="utf-8",
86
+ )
87
+
88
+ print(
89
+ f"wrote {out_path.relative_to(root)} ({len(entries)} ref(s): "
90
+ f"{', '.join(r for r, _ in entries)}; {len(manifests)} manifest(s))"
91
+ )
59
92
  return 0
60
93
 
61
94
 
@@ -53,7 +53,12 @@ from typing import Callable
53
53
 
54
54
  from metaobjects import MetaDataLoader
55
55
  from metaobjects.errors import ParseError
56
- from metaobjects.config.dependencies import Collection, imported_from, refuse_unowned_packages
56
+ from metaobjects.config.dependencies import (
57
+ Collection,
58
+ imported_from,
59
+ refuse_library_package_misuse,
60
+ refuse_unowned_packages,
61
+ )
57
62
  from metaobjects.loader.meta_data_loader import LoadResult
58
63
  from metaobjects.loader.sources import FileSource
59
64
  from metaobjects.meta.core.object.meta_object import MetaObject
@@ -119,22 +124,29 @@ def _pkg_of(node: MetaData) -> str:
119
124
  return "" if i == -1 else key[:i]
120
125
 
121
126
 
122
- def _default_generators() -> list[Generator]:
123
- """The default codegen suite — the no-config generators every project gets.
127
+ #: The error a run with no generator selection reports.
128
+ #:
129
+ #: There is no default suite. This port used to run EIGHT generators for a caller who
130
+ #: named none — entity, router, filter-allowlist, names, payload, output-parser,
131
+ #: output-prompt, extractor — which is a shape nobody chose. Java has never had a
132
+ #: default set and has been right all along; TypeScript and C# dropped theirs in the
133
+ #: same change.
134
+ #:
135
+ #: Deciding WHICH code an application needs belongs to whoever is building it —
136
+ #: increasingly an LLM working in the repo, which is well able to make that call given a
137
+ #: truthful catalog and is badly served by a default that pre-empts it. ``--list`` is
138
+ #: that catalog.
139
+ NO_GENERATORS_SELECTED = (
140
+ "gen: no generators selected. Nothing is generated until you choose it — "
141
+ "pass --generators <a,b,c>. See the catalog: metaobjects gen --list"
142
+ )
124
143
 
125
- ``template_generator`` is excluded: it requires a caller-supplied text
126
- provider + Mustache template and is not a zero-config per-entity emitter.
127
- """
128
- return [
129
- entity_model(),
130
- router_generator(),
131
- filter_allowlist_generator(),
132
- names_generator(),
133
- payload_vo_generator(),
134
- output_parser_generator(),
135
- output_prompt_generator(),
136
- extractor_generator(),
137
- ]
144
+
145
+ class NoGeneratorsSelectedError(ValueError):
146
+ """Raised when a codegen run names no generator. Carries the usage message."""
147
+
148
+ def __init__(self) -> None:
149
+ super().__init__(NO_GENERATORS_SELECTED)
138
150
 
139
151
 
140
152
  def _resolve_providers(specs: list[str] | None) -> tuple[list[object], list[str]]:
@@ -338,6 +350,11 @@ def _load_collection_result(
338
350
  result = loader.load([*lib_sources, *sources])
339
351
  if not result.errors:
340
352
  refuse_unowned_packages(result.root, collection.imported_packages, collection.imported_nodes)
353
+ # FR-043 §3.4 / §3.5 — the same rule for a shipped LIBRARY's package, where the
354
+ # two ways to get it wrong are opposite: a node the library also declares (an
355
+ # ejected copy, still opted in) and one it does not (a new node in someone
356
+ # else's package).
357
+ refuse_library_package_misuse(result.root, libraries)
341
358
  return result
342
359
 
343
360
 
@@ -507,7 +524,11 @@ def _run_suite(
507
524
  # verify path (those pass gen_state_dir=None and record nothing at all).
508
525
  baseline=baseline,
509
526
  )
510
- suite = generators if generators is not None else _default_generators()
527
+ # No default suite — see NO_GENERATORS_SELECTED. A caller that names none gets a
528
+ # usage error and an empty out dir, never a shape this CLI picked.
529
+ if not generators:
530
+ raise NoGeneratorsSelectedError
531
+ suite = generators
511
532
  result = run_gen(config, root, generators=suite, entity_filter=entity_filter, select=select)
512
533
  for warning in result.warnings:
513
534
  print(f"warning: {warning}")
@@ -885,6 +906,11 @@ def _cmd_gen(args: argparse.Namespace) -> int:
885
906
  for msg in gen_errors:
886
907
  print(f" {msg}", file=sys.stderr)
887
908
  return 1
909
+ else:
910
+ # Codegen is opt-in: refuse here, at the door, rather than letting the run reach
911
+ # the generator loop and fail with an empty out dir half-created.
912
+ print(f"error: {NO_GENERATORS_SELECTED}", file=sys.stderr)
913
+ return 2
888
914
 
889
915
  # SP-1: declarative Mustache generators from a JSON template-spec. Their output
890
916
  # is format-agnostic (text/markdown/csv/json/xml/html), so they run as a SECOND,
@@ -1380,12 +1406,35 @@ def _verify_codegen(args: argparse.Namespace) -> int:
1380
1406
  print(spec_err, file=sys.stderr)
1381
1407
  return 1
1382
1408
 
1409
+ # `verify --codegen` re-runs the SELECTION and compares. Codegen is opt-in, so the
1410
+ # selection has to be named — with none, there is no generated output to check, and
1411
+ # saying so beats silently regenerating a suite this project never asked for and
1412
+ # convicting every file of being missing.
1413
+ selection: list[Generator] | None = None
1414
+ if getattr(args, "generators", None):
1415
+ selection, gen_errors = _resolve_generators(args.generators)
1416
+ if gen_errors:
1417
+ print("error: invalid --generators selection:", file=sys.stderr)
1418
+ for msg in gen_errors:
1419
+ print(f" {msg}", file=sys.stderr)
1420
+ return 1
1421
+ elif not spec_gens:
1422
+ print(
1423
+ "verify --codegen: no generators selected, so there is no generated output "
1424
+ "to check. Pass --generators <a,b,c> naming the same suite `gen` ran "
1425
+ "(metaobjects gen --list is the catalog).",
1426
+ )
1427
+ return 0
1428
+
1383
1429
  with tempfile.TemporaryDirectory() as tmp:
1384
1430
  entities = _parse_entities(getattr(args, "entities", None))
1385
- written, errors = _generate(
1386
- args.metadata_dir, tmp, None, entities, strict=strict, providers=providers,
1387
- column_naming=column_naming,
1388
- )
1431
+ written: list[str] = []
1432
+ errors: list[str] = []
1433
+ if selection is not None:
1434
+ written, errors = _generate(
1435
+ args.metadata_dir, tmp, selection, entities, strict=strict,
1436
+ providers=providers, column_naming=column_naming,
1437
+ )
1389
1438
  if errors:
1390
1439
  print("error: failed to load metadata:", file=sys.stderr)
1391
1440
  for msg in errors:
@@ -1458,6 +1507,22 @@ def _verify_codegen_neutral_fallback(args: argparse.Namespace) -> int:
1458
1507
  if not providers_ok:
1459
1508
  return 1
1460
1509
 
1510
+ # Same rule as _verify_codegen: the selection must be named, because there is no
1511
+ # default suite to regenerate and diff against.
1512
+ if not getattr(args, "generators", None):
1513
+ print(
1514
+ "verify --codegen: no generators selected, so there is no generated output "
1515
+ "to check. Pass --generators <a,b,c> naming the same suite `gen` ran "
1516
+ "(metaobjects gen --list is the catalog).",
1517
+ )
1518
+ return 0
1519
+ selection, gen_errors = _resolve_generators(args.generators)
1520
+ if gen_errors:
1521
+ print("error: invalid --generators selection:", file=sys.stderr)
1522
+ for msg in gen_errors:
1523
+ print(f" {msg}", file=sys.stderr)
1524
+ return 1
1525
+
1461
1526
  with tempfile.TemporaryDirectory() as tmp:
1462
1527
  entities = _parse_entities(getattr(args, "entities", None))
1463
1528
  root, load_errors = _load_root_from_collection(collection, strict=strict, providers=providers)
@@ -1475,7 +1540,7 @@ def _verify_codegen_neutral_fallback(args: argparse.Namespace) -> int:
1475
1540
  return 2
1476
1541
 
1477
1542
  _run_suite(
1478
- root, tmp, None, entities, gen_state_dir=None, column_naming=column_naming,
1543
+ root, tmp, selection, entities, gen_state_dir=None, column_naming=column_naming,
1479
1544
  select=collection.in_scope,
1480
1545
  )
1481
1546
  expected = _relative_set(Path(tmp))
@@ -1903,9 +1968,9 @@ def _build_parser() -> argparse.ArgumentParser:
1903
1968
  "--generators",
1904
1969
  default=None,
1905
1970
  help=(
1906
- "comma-separated STABLE generator names to run (e.g. entity,routes). "
1907
- "Resolved via the registry; omit to run the default suite. "
1908
- "See `gen --list`."
1971
+ "REQUIRED — comma-separated STABLE generator names to run "
1972
+ "(e.g. entity,routes). Codegen is opt-in: there is no default suite, so a "
1973
+ "run that names none is a usage error. See `gen --list` for the catalog."
1909
1974
  ),
1910
1975
  )
1911
1976
  gen.add_argument(
@@ -2134,6 +2199,15 @@ def _build_parser() -> argparse.ArgumentParser:
2134
2199
  default=None,
2135
2200
  help="verify only this named target from the config (default: every target)",
2136
2201
  )
2202
+ verify.add_argument(
2203
+ "--generators",
2204
+ default=None,
2205
+ help=(
2206
+ "comma-separated STABLE generator names — must MATCH the `gen` that "
2207
+ "produced --out. `verify --codegen` re-runs the selection and diffs; with "
2208
+ "none named there is nothing to check and it says so."
2209
+ ),
2210
+ )
2137
2211
  verify.set_defaults(func=_cmd_verify)
2138
2212
 
2139
2213
  agent_docs = sub.add_parser(
@@ -5,11 +5,20 @@ GENERATED_MARKER = "@generated by metaobjects"
5
5
 
6
6
 
7
7
  def generated_header(entity_name: str, fqn: str) -> str:
8
- """Line-1 header for every emitted module. Detected by the overwrite policy."""
8
+ """Line-1 header for every emitted module. Detected by the overwrite policy.
9
+
10
+ Line 3 used to read ``Customize via <name>_extra.py in this directory``, the exact
11
+ wording the TypeScript emitters carried. It asserted a plugin point no port has: a
12
+ sibling module is safe because codegen only writes the paths it records, never
13
+ because of its name, and nothing imports it for you. See #367 for what the TS
14
+ spelling cost in a real build, and ``docs/features/own-your-codegen.md`` for the
15
+ convention as it actually works. Keep this line and
16
+ ``codegen-ts/src/constants.ts``'s ``sidecarLine`` saying the same thing.
17
+ """
9
18
  return (
10
19
  f"# {GENERATED_MARKER} — DO NOT EDIT.\n"
11
20
  f"# Source metadata: {entity_name} ({fqn})\n"
12
- f"# Customize via {entity_name}_extra.py in this directory.\n"
21
+ f"# Extend in your own module (e.g. {entity_name}_extra.py) — nothing imports it for you.\n"
13
22
  )
14
23
 
15
24
 
@@ -6,9 +6,11 @@ the cross-port contract: the same logical generator carries the same stable name
6
6
  in every port. This module is the discoverability + identity surface behind
7
7
  ``metaobjects gen --list`` and the ``--generators a,b`` selection path.
8
8
 
9
- It is ADDITIVE. The default suite in ``cli.py`` (``_default_generators``) and the
10
- ``run_gen(..., generators=[...])`` factory-array path keep working unchanged — the
11
- registry powers ``--list`` and stable identity; it does not replace those paths.
9
+ It is the ONLY name-based door. ADR-0034 Amendment 2 made codegen opt-in and DELETED
10
+ the default suite this note used to name (``cli._default_generators``): a run that
11
+ selects no generator generates nothing and raises ``NoGeneratorsSelectedError``. The
12
+ ``run_gen(..., generators=[...])`` factory-array path remains for in-process callers,
13
+ where ``generators`` is likewise required.
12
14
 
13
15
  The registry's name set is conformance-tested for SET EQUALITY against the Python
14
16
  slice of the canonical manifest
@@ -45,10 +47,27 @@ from metaobjects.render.verify import InMemoryProvider
45
47
 
46
48
  GeneratorTier = str # "native" | "neutral"
47
49
 
50
+ #: The six layers a generator can belong to — the axis an adopter SELECTS BY, gated
51
+ #: cross-port against the manifest exactly as ``tier`` is. Six, not ten: an earlier
52
+ #: draft split ``capability`` four ways, each with ONE member, and a layer with one
53
+ #: member does no grouping work. ``capability`` holds the generators the MODEL has
54
+ #: already chosen (you declared a ``template.prompt``), which is why they are found
55
+ #: by probing a real model rather than by browsing a taxonomy.
56
+ GENERATOR_LAYERS: tuple[str, ...] = (
57
+ "model",
58
+ "persistence",
59
+ "api",
60
+ "client",
61
+ "docs",
62
+ "capability",
63
+ )
64
+
65
+ GeneratorLayer = str # one of GENERATOR_LAYERS
66
+
48
67
 
49
68
  @dataclass(frozen=True)
50
69
  class GeneratorEntry:
51
- """A registry entry: stable name + one-line description + tier + factory."""
70
+ """A registry entry: stable name + one-line description + tier + layer + factory."""
52
71
 
53
72
  #: Stable, cross-port-consistent id. Equals the registry map key.
54
73
  name: str
@@ -56,6 +75,8 @@ class GeneratorEntry:
56
75
  description: str
57
76
  #: "native" = recommended ``metaobjects gen`` suite; "neutral" = ``meta docs``-owned.
58
77
  tier: GeneratorTier
78
+ #: The selection axis — one of :data:`GENERATOR_LAYERS`. Gated cross-port.
79
+ layer: GeneratorLayer
59
80
  #: Constructs the generator with sensible defaults. Calling it must not throw.
60
81
  factory: Callable[[], Generator]
61
82
 
@@ -89,72 +110,84 @@ def _render_helper_default() -> Generator:
89
110
 
90
111
 
91
112
  #: Stable name -> GeneratorEntry. The 11 native generators whose manifest `ports`
92
- #: include `python` (ADR-0021 D3). Set-equality conformance-tested vs the manifest.
113
+ #: include `python` (ADR-0021 D3). Set equality, tier AND layer are conformance-tested
114
+ #: against the manifest.
93
115
  GENERATOR_REGISTRY: dict[str, GeneratorEntry] = {
94
116
  "entity": GeneratorEntry(
95
117
  name="entity",
96
118
  description="Per-entity model/class — the entity module (table-backed or value object).",
97
119
  tier="native",
120
+ layer="model",
98
121
  factory=entity_model,
99
122
  ),
100
123
  "routes": GeneratorEntry(
101
124
  name="routes",
102
125
  description="Per-entity REST endpoint surface (controllers / routes / router).",
103
126
  tier="native",
127
+ layer="api",
104
128
  factory=router_generator,
105
129
  ),
106
130
  "output-parser": GeneratorEntry(
107
131
  name="output-parser",
108
132
  description="Per-template tolerant output parser (recover-on-receipt).",
109
133
  tier="native",
134
+ layer="capability",
110
135
  factory=output_parser_generator,
111
136
  ),
112
137
  "output-prompt": GeneratorEntry(
113
138
  name="output-prompt",
114
139
  description="Per-template output-format prompt fragment generator.",
115
140
  tier="native",
141
+ layer="capability",
116
142
  factory=output_prompt_generator,
117
143
  ),
118
144
  "render-helper": GeneratorEntry(
119
145
  name="render-helper",
120
146
  description="Per-template.output render helper (document/email typed wrappers).",
121
147
  tier="native",
148
+ layer="capability",
122
149
  factory=_render_helper_default,
123
150
  ),
124
151
  "extractor": GeneratorEntry(
125
152
  name="extractor",
126
153
  description="Per-template strict typed extract<Name> helper (strict payload extraction).",
127
154
  tier="native",
155
+ layer="capability",
128
156
  factory=extractor_generator,
129
157
  ),
130
158
  "template": GeneratorEntry(
131
159
  name="template",
132
160
  description="Generic Mustache template primitive (walk + template -> files).",
133
161
  tier="native",
162
+ layer="capability",
134
163
  factory=_template_primitive,
135
164
  ),
136
165
  "filter-allowlist": GeneratorEntry(
137
166
  name="filter-allowlist",
138
167
  description="Per-entity REST filter allowlist (queryable-field guard).",
139
168
  tier="native",
169
+ layer="api",
140
170
  factory=filter_allowlist_generator,
141
171
  ),
142
172
  "names": GeneratorEntry(
143
173
  name="names",
144
174
  description="Per-entity physical database name constants (table/view name, schema, column names).",
145
175
  tier="native",
176
+ layer="model",
146
177
  factory=names_generator,
147
178
  ),
148
179
  "payload": GeneratorEntry(
149
180
  name="payload",
150
181
  description="Per-template payload value object (the strict payload type).",
151
182
  tier="native",
183
+ layer="capability",
152
184
  factory=payload_vo_generator,
153
185
  ),
154
186
  "trace-helper": GeneratorEntry(
155
187
  name="trace-helper",
156
188
  description="Per-entity typed record<Entity> LLM-trace helper (extract + buildLlmCallRow + persist).",
157
189
  tier="native",
190
+ layer="capability",
158
191
  factory=trace_helper_generator,
159
192
  ),
160
193
  }
@@ -60,10 +60,12 @@ from metaobjects.meta.core.field.meta_field import MetaField
60
60
  from metaobjects.meta.persistence.db import db_constants as dbc
61
61
  from metaobjects.meta.core.identity.identity_constants import (
62
62
  IDENTITY_ATTR_FIELDS,
63
- IDENTITY_REFERENCE_ATTR_REFERENCES,
64
63
  IDENTITY_SUBTYPE_REFERENCE,
65
64
  )
66
65
  from metaobjects.meta.core.object.meta_object import MetaObject
66
+ from metaobjects.meta.core.relationship.relationship_references import (
67
+ reference_target_entity,
68
+ )
67
69
  from metaobjects.meta.persistence.source.source_constants import SOURCE_KIND_TABLE
68
70
  from metaobjects.naming import DEFAULT_COLUMN_NAMING
69
71
  from metaobjects.shared.base_types import TYPE_IDENTITY
@@ -269,13 +271,15 @@ def reverse_fks_for(entity: MetaObject) -> list[ReverseFk]:
269
271
  fk_field = fields[0]
270
272
  elif isinstance(fields, str) and fields:
271
273
  fk_field = fields.split(",")[0].strip() or None
272
- references = c.get_meta_attr(IDENTITY_REFERENCE_ATTR_REFERENCES) # ADR-0039: resolving (identity attr)
273
- target = (
274
- references[references.rfind(PACKAGE_SEP) + len(PACKAGE_SEP):]
275
- if isinstance(references, str) and PACKAGE_SEP in references
276
- else references
277
- )
278
- if not fk_field or not isinstance(target, str) or not target:
274
+ # #368 fallout: @references may be the dotted `Entity.field` /
275
+ # `Entity.fieldA,fieldB` explicit-fields form (e.g. "acme::sport::Team.id"),
276
+ # not just a bare/qualified entity name. reference_target_entity() already
277
+ # drops that dotted tail (ADR-0039: resolving); strip_package here then bares
278
+ # the remaining qualified entity name, same as the pre-existing package strip.
279
+ target = reference_target_entity(c)
280
+ if isinstance(target, str) and PACKAGE_SEP in target:
281
+ target = target[target.rfind(PACKAGE_SEP) + len(PACKAGE_SEP):]
282
+ if not fk_field or not target:
279
283
  continue
280
284
  out.append(ReverseFk(fk_field=fk_field, target_entity=target))
281
285
  return out
@@ -54,13 +54,31 @@ from metaobjects.meta.meta_data import MetaData
54
54
  from metaobjects.meta.template import template_constants as tc
55
55
  from metaobjects.meta.template.meta_template import MetaTemplate
56
56
  from metaobjects.shared.base_types import TYPE_TEMPLATE
57
+ from metaobjects.library.library_sources import LIBRARY_MANIFESTS
57
58
  from metaobjects.shared.separators import PACKAGE_SEP
58
59
 
59
60
  _GENERATOR_NAME = "trace-helper"
60
61
 
61
- #: The abstract base entity a trace entity must (transitively) ``extends``.
62
- #: Cross-port constant — mirrors TS ``LLM_CALL_BASE`` / Java ``LLM_CALL_BASE``.
63
- LLM_CALL_BASE = "LlmCallBase"
62
+ def _anchor_fqns() -> frozenset[str]:
63
+ """FQNs of the library nodes this generator keys on, read from the shipped
64
+ ``library.json`` manifests (FR-043 §6) rather than hard-coded here.
65
+
66
+ What it replaces: ``LLM_CALL_BASE = "LlmCallBase"``, compared against
67
+ ``MetaData.name`` (the SHORT name) anywhere in the super chain — so any adopter
68
+ entity of that name, in any package, triggered a helper that writes the shipped
69
+ base's columns. An anchor is fully qualified and is resolved to a node below.
70
+ """
71
+ out: set[str] = set()
72
+ for manifest in LIBRARY_MANIFESTS.values():
73
+ for gen in manifest.get("generators", []):
74
+ if gen.get("name") == _GENERATOR_NAME and gen.get("anchor"):
75
+ out.add(gen["anchor"])
76
+ return frozenset(out)
77
+
78
+
79
+ #: The anchor FQNs, resolved once per process from the embedded manifests.
80
+ #: Mirrors TS ``anchorFqns()`` / Java ``LlmTraceHelperGenerator.ANCHOR_FQNS``.
81
+ ANCHOR_FQNS = _anchor_fqns()
64
82
 
65
83
 
66
84
  def _pkg_of(node: MetaData) -> str:
@@ -88,15 +106,18 @@ def _snake_case(name: str) -> str:
88
106
 
89
107
 
90
108
  def _extends_base(entity: MetaObject) -> bool:
91
- """Walk the resolved super chain looking for a node SHORT-named
92
- :data:`LLM_CALL_BASE`. ``MetaData.name`` holds the short name only (the package
93
- lives on ``MetaData.package``), so a plain ``name`` compare is the short-name
94
- test — mirrors the Java ``getShortName()`` walk and the TS ``superResolved``
95
- walk."""
109
+ """Walk the resolved super chain looking for one of :data:`ANCHOR_FQNS`.
110
+
111
+ The FULLY-QUALIFIED name, via ``resolution_key()``: within one loaded root an FQN
112
+ identifies exactly one node (a same-name redeclaration merges), so this is the
113
+ node-identity compare the TypeScript port makes against the resolved anchor node,
114
+ and the Java port makes against ``getName()``."""
115
+ if not ANCHOR_FQNS:
116
+ return False
96
117
  cur = entity.super_data
97
118
  visited: set[int] = set()
98
119
  while cur is not None and id(cur) not in visited:
99
- if cur.name == LLM_CALL_BASE:
120
+ if cur.resolution_key() in ANCHOR_FQNS:
100
121
  return True
101
122
  visited.add(id(cur))
102
123
  cur = cur.super_data
@@ -125,7 +146,7 @@ def render_trace_helper(entity: MetaObject, root: MetaData) -> str | None:
125
146
  """Render one ``record_<entity>.py`` for a concrete trace ``object.entity``.
126
147
 
127
148
  Returns ``None`` when the entity is not a trace-helper target (abstract, not
128
- ``LlmCallBase``-derived, no nested ``template.prompt``, or that prompt carries
149
+ derived from a library anchor, no nested ``template.prompt``, or that prompt carries
129
150
  neither ``@responseRef`` nor ``@payloadRef``).
130
151
 
131
152
  Raises ``ValueError`` when the prompt's ``@responseRef`` does not resolve to an
@@ -515,6 +515,88 @@ def refuse_unowned_packages(
515
515
  )
516
516
 
517
517
 
518
+ def refuse_library_package_misuse(
519
+ root: MetaData,
520
+ selection: Sequence[str] | None,
521
+ ) -> None:
522
+ """FR-043 §3.4 / §3.5 — refuse the two ways an adopter's own file lands in a
523
+ shipped library's package while that library is opted in.
524
+
525
+ Both are SILENT otherwise, and they fail in opposite directions:
526
+
527
+ the EJECTED COPY
528
+ ``meta eject <lib>`` hands you the library's YAML to own, and the next step it
529
+ prints is to remove the library from ``libraries``. Skip that and both trees
530
+ load: the copy merges into the shipped node, so ADDITIONS take and DELETIONS do
531
+ not, because the library still declares what you removed
532
+ (``ERR_LIBRARY_PACKAGE_COLLISION``).
533
+
534
+ the NEW NODE
535
+ something of your own declared into ``metaobjects::<lib>``, where a later
536
+ release of the library may ship a node of that name and merge into it
537
+ (``ERR_LIBRARY_PACKAGE_NOT_OWNED``).
538
+
539
+ An ``overlay: true`` redeclaration is the documented adaptation door (§3.4) and is
540
+ deliberately untouched — ``is_merge`` is the loader's own record that the flag was
541
+ honoured, so this cannot mistake the two. Mirrors the TS
542
+ ``refuseLibraryPackageMisuse`` (``sdk/src/memory.ts``); called AFTER the loader's
543
+ own errors for the same reason its sibling above is.
544
+
545
+ No-op for a project that opts into no library.
546
+ """
547
+ if not selection:
548
+ return
549
+ from metaobjects.library.library_sources import (
550
+ LIBRARY_MANIFESTS,
551
+ is_library_file_id,
552
+ split_layer_token,
553
+ )
554
+
555
+ owner: dict[str, str] = {}
556
+ for token in selection:
557
+ library = split_layer_token(token)[0]
558
+ for pkg in LIBRARY_MANIFESTS.get(library, {}).get("packages", []):
559
+ owner[pkg] = library
560
+ if not owner:
561
+ return
562
+
563
+ # ADR-0039 SANCTIONED own-accessor case: a root-level scan, exactly as the
564
+ # dependency refusal above — `MetaRoot` has no super, and the question is "what did
565
+ # this tree declare at the top level".
566
+ for node in root.own_children():
567
+ key = node.resolution_key()
568
+ library = owner.get(package_of_resolution_key(key))
569
+ if library is None:
570
+ continue
571
+ files = getattr(node.source, "files", None) or []
572
+ if not any(not is_library_file_id(f) for f in files):
573
+ continue # the library's own node, untouched
574
+ if getattr(node, "is_merge", False):
575
+ continue # a marked overlay — the documented door
576
+ if any(is_library_file_id(f) for f in files):
577
+ raise ParseError(
578
+ f'"{key}" is declared by your own metadata AND by the shipped library '
579
+ f'"{library}", which this project opts into. The two merge silently and '
580
+ "asymmetrically: additions in your copy take effect and DELETIONS do not, "
581
+ "because the library still declares what you removed. Remove "
582
+ f'"{library}" from \'libraries\' in .metaobjects/config.json — you own the '
583
+ "metadata now — or delete your copy and amend the library with "
584
+ "'overlay: true' on the nodes you want to change.",
585
+ code=ErrorCode.ERR_LIBRARY_PACKAGE_COLLISION,
586
+ )
587
+ raise ParseError(
588
+ f'"{key}" is declared here, but the package '
589
+ f'"{package_of_resolution_key(key)}" belongs to the shipped library '
590
+ f'"{library}", which this project opts into. A later release of that library '
591
+ "may ship a node of this name and merge into yours. Declare it in a package "
592
+ "this project owns and 'extends' the library's node if it needs its shape; if "
593
+ "it was meant to AMEND a library node, give it that node's name and "
594
+ f"'overlay: true'; if you want this design outright, run 'meta eject {library}' "
595
+ f'and remove "{library}" from \'libraries\'.',
596
+ code=ErrorCode.ERR_LIBRARY_PACKAGE_NOT_OWNED,
597
+ )
598
+
599
+
518
600
  @dataclass(frozen=True)
519
601
  class Collection:
520
602
  """Everything the FR-023-aware source ladder resolved for one project:
@@ -127,6 +127,15 @@ class ErrorCode(str, Enum):
127
127
  ERR_COLLECTION_NOT_FOUND = "ERR_COLLECTION_NOT_FOUND"
128
128
  # FR-023 — a declared dependency's transport could not locate a directory holding
129
129
  # metaobjects.pkg.json.
130
+ # FR-043: .metaobjects/config.json's `libraries` names a shipped library or layer
131
+ # this build does not have. Refused with the available tokens rather than skipped —
132
+ # skipped, it resurfaces as ERR_UNRESOLVED_SUPER against the adopter's own metadata.
133
+ ERR_UNKNOWN_LIBRARY = "ERR_UNKNOWN_LIBRARY"
134
+ # FR-043: a node is declared by BOTH an adopter's own metadata and a shipped library the project opts into — the `meta eject <lib>` copy with the library still in `libraries`. The two merge silently and ASYMMETRICALLY: additions take, deletions do not, because the library still declares what was removed.
135
+ # Raised by the TypeScript SDK's load path; registered in every port so the shared corpus list stays one set.
136
+ ERR_LIBRARY_PACKAGE_COLLISION = "ERR_LIBRARY_PACKAGE_COLLISION"
137
+ # FR-043: a NEW top-level node is declared into a package a shipped library owns while that library is opted in — a later release of the library may ship a node of that name and merge into it. `overlay: true` on one of the library's OWN nodes is the documented amendment door and is untouched.
138
+ ERR_LIBRARY_PACKAGE_NOT_OWNED = "ERR_LIBRARY_PACKAGE_NOT_OWNED"
130
139
  ERR_DEPENDENCY_UNRESOLVED = "ERR_DEPENDENCY_UNRESOLVED"
131
140
  # FR-023 — a dependency's metaobjects.pkg.json fails its schema, names a different
132
141
  # dependency, points at a missing/hash-mismatched artifact, or the artifact does not