metaobjects 1.0.4__tar.gz → 1.0.5rc1__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 (453) hide show
  1. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/PKG-INFO +1 -1
  2. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/pyproject.toml +1 -1
  3. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/library/embedded_library.py +1 -1
  4. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/requirement/requirement_constants.py +4 -2
  5. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/requirement.json +2 -2
  6. metaobjects-1.0.5rc1/tests/codegen/test_codegen_compile_conformance.py +156 -0
  7. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/.gitignore +0 -0
  8. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/LICENSE +0 -0
  9. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/README.md +0 -0
  10. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/hatch_build.py +0 -0
  11. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/scripts/generate_embedded_library.py +0 -0
  12. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/__init__.py +0 -0
  13. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/agent_context/__init__.py +0 -0
  14. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/agent_context/scaffold.py +0 -0
  15. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/apidocs/__init__.py +0 -0
  16. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/apidocs/api_model.py +0 -0
  17. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/apidocs/builder.py +0 -0
  18. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/apidocs/naming.py +0 -0
  19. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/apidocs/paths.py +0 -0
  20. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/apidocs/renderer.py +0 -0
  21. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/attr_class_map.py +0 -0
  22. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/cli.py +0 -0
  23. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
  24. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/__init__.py +0 -0
  25. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/collision_names.py +0 -0
  26. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/config.py +0 -0
  27. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/constants.py +0 -0
  28. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
  29. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
  30. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/format.py +0 -0
  31. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
  32. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generator.py +0 -0
  33. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generator_registry.py +0 -0
  34. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/__init__.py +0 -0
  35. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/entity_model.py +0 -0
  36. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
  37. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
  38. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/find_inbound.py +0 -0
  39. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
  40. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
  41. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/names_generator.py +0 -0
  42. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
  43. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
  44. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/payload_vo_generator.py +0 -0
  45. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
  46. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/router_generator.py +0 -0
  47. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/template_generator.py +0 -0
  48. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
  49. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
  50. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/instance_artifacts.py +0 -0
  51. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/metaobjects-config.schema.json +0 -0
  52. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
  53. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/overwrite_policy.py +0 -0
  54. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/project_config.py +0 -0
  55. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/runner.py +0 -0
  56. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/runtime/__init__.py +0 -0
  57. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
  58. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
  59. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
  60. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
  61. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
  62. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/codegen/type_map.py +0 -0
  63. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/config/__init__.py +0 -0
  64. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/config/dependencies.py +0 -0
  65. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/config/neutral_config.py +0 -0
  66. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/config/source_resolver.py +0 -0
  67. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/core_types.py +0 -0
  68. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/datatype.py +0 -0
  69. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/documentation/__init__.py +0 -0
  70. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/documentation/doc_constants.py +0 -0
  71. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/documentation/doc_provider.py +0 -0
  72. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/documentation/doc_schema.py +0 -0
  73. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/errors.py +0 -0
  74. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/library/__init__.py +0 -0
  75. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/library/library_sources.py +0 -0
  76. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/__init__.py +0 -0
  77. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/merge.py +0 -0
  78. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/meta_data_loader.py +0 -0
  79. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/registered_validation.py +0 -0
  80. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/sources/__init__.py +0 -0
  81. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/sources/directory_source.py +0 -0
  82. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/sources/file_source.py +0 -0
  83. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
  84. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/sources/uri_source.py +0 -0
  85. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/validate_discriminator.py +0 -0
  86. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/validate_enum_normalize_ambiguity.py +0 -0
  87. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/validate_field_mutability.py +0 -0
  88. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/validate_source_escapes.py +0 -0
  89. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
  90. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
  91. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/loader/validation_passes.py +0 -0
  92. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/__init__.py +0 -0
  93. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/__init__.py +0 -0
  94. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/attr/__init__.py +0 -0
  95. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
  96. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
  97. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/field/__init__.py +0 -0
  98. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/field/field_constants.py +0 -0
  99. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/field/meta_field.py +0 -0
  100. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/identity/__init__.py +0 -0
  101. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
  102. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
  103. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/index/__init__.py +0 -0
  104. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/index/index_constants.py +0 -0
  105. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/index/meta_index.py +0 -0
  106. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/object/__init__.py +0 -0
  107. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/object/meta_object.py +0 -0
  108. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
  109. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
  110. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/object/object_constants.py +0 -0
  111. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/object/object_extract.py +0 -0
  112. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/object/value_object.py +0 -0
  113. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
  114. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
  115. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
  116. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
  117. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/relationship/relationship_references.py +0 -0
  118. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/requirement/__init__.py +0 -0
  119. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/requirement/meta_requirement.py +0 -0
  120. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/validator/__init__.py +0 -0
  121. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
  122. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/meta_data.py +0 -0
  123. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/meta_root.py +0 -0
  124. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/__init__.py +0 -0
  125. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
  126. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
  127. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
  128. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
  129. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
  130. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
  131. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
  132. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
  133. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
  134. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/__init__.py +0 -0
  135. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
  136. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
  137. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
  138. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
  139. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
  140. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
  141. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
  142. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
  143. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/provider_extends.py +0 -0
  144. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/template/__init__.py +0 -0
  145. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/template/meta_template.py +0 -0
  146. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/template/prompt_provider.py +0 -0
  147. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/meta/template/template_constants.py +0 -0
  148. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/naming.py +0 -0
  149. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/naming_refs.py +0 -0
  150. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/parser.py +0 -0
  151. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/parser_yaml.py +0 -0
  152. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/provider.py +0 -0
  153. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/py.typed +0 -0
  154. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/registry.py +0 -0
  155. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/registry_manifest.py +0 -0
  156. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/__init__.py +0 -0
  157. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/email_document.py +0 -0
  158. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/escapers.py +0 -0
  159. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
  160. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/__init__.py +0 -0
  161. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/coerce.py +0 -0
  162. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/extract.py +0 -0
  163. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/extract_map.py +0 -0
  164. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
  165. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/locate.py +0 -0
  166. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/normalize.py +0 -0
  167. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/strip.py +0 -0
  168. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/types.py +0 -0
  169. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
  170. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/filesystem_provider.py +0 -0
  171. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/payload_accessors.py +0 -0
  172. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/prompt/__init__.py +0 -0
  173. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
  174. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
  175. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/prompt/prompt_field.py +0 -0
  176. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
  177. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/prompt/prompt_style.py +0 -0
  178. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/renderer.py +0 -0
  179. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/render/verify.py +0 -0
  180. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/runtime/__init__.py +0 -0
  181. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/runtime/llm_recorder.py +0 -0
  182. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/runtime/n2m_resolver.py +0 -0
  183. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/runtime/object_manager.py +0 -0
  184. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/runtime/tph.py +0 -0
  185. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/scope.py +0 -0
  186. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/serializer_json.py +0 -0
  187. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/shared/__init__.py +0 -0
  188. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/shared/base_types.py +0 -0
  189. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/shared/separators.py +0 -0
  190. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/shared/structural.py +0 -0
  191. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/source/__init__.py +0 -0
  192. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/source/error_source.py +0 -0
  193. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/source/json_path.py +0 -0
  194. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/source/semantic_diff.py +0 -0
  195. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/source/yaml_positions.py +0 -0
  196. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/source_resolution.py +0 -0
  197. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/__init__.py +0 -0
  198. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/attr.json +0 -0
  199. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/db.json +0 -0
  200. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/documentation.json +0 -0
  201. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/field.json +0 -0
  202. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/identity.json +0 -0
  203. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/index.json +0 -0
  204. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/layout.json +0 -0
  205. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/object.json +0 -0
  206. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/origin.json +0 -0
  207. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/prompt.json +0 -0
  208. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/relationship.json +0 -0
  209. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/source.json +0 -0
  210. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/template.json +0 -0
  211. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
  212. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/ui.json +0 -0
  213. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/validator.json +0 -0
  214. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/spec_metamodel/view.json +0 -0
  215. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/super_resolve.py +0 -0
  216. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/validation_types.py +0 -0
  217. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/src/metaobjects/yaml_desugar.py +0 -0
  218. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/__init__.py +0 -0
  219. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/__init__.py +0 -0
  220. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/gen_suite.py +0 -0
  221. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
  222. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/extends/expected/Program.py +0 -0
  223. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/extends/meta.json +0 -0
  224. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
  225. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
  226. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/nested-array/meta.json +0 -0
  227. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
  228. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/scalars/expected/Report.py +0 -0
  229. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/scalars/meta.json +0 -0
  230. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
  231. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/golden/vanilla/meta.json +0 -0
  232. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_abstract_conformance.py +0 -0
  233. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_api_docs_builder.py +0 -0
  234. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_api_docs_paths.py +0 -0
  235. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli.py +0 -0
  236. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli_config_gen.py +0 -0
  237. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli_config_verify.py +0 -0
  238. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli_dependencies.py +0 -0
  239. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli_providers.py +0 -0
  240. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli_registry.py +0 -0
  241. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli_staleness_nudge.py +0 -0
  242. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli_verify_strict.py +0 -0
  243. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_cli_verify_subverbs.py +0 -0
  244. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_constants_config.py +0 -0
  245. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_entity_model.py +0 -0
  246. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_enum_conformance.py +0 -0
  247. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
  248. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_extract_tier_collision.py +0 -0
  249. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_extractor_generator.py +0 -0
  250. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_filter_allowlist_generator.py +0 -0
  251. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_format.py +0 -0
  252. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
  253. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_fr010_output_codegen.py +0 -0
  254. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
  255. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_gen_state_keying.py +0 -0
  256. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_generator.py +0 -0
  257. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_generator_extension_seams.py +0 -0
  258. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_golden.py +0 -0
  259. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
  260. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_inheritance_conformance.py +0 -0
  261. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_instance_artifacts.py +0 -0
  262. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_m2m_codegen.py +0 -0
  263. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_names_extends_chain.py +0 -0
  264. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_names_generator.py +0 -0
  265. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_no_magic_physical_names.py +0 -0
  266. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_origin_nullability.py +0 -0
  267. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_output_parser_generator.py +0 -0
  268. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_overwrite_policy.py +0 -0
  269. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_overwrite_policy_hash.py +0 -0
  270. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_payload_vo_generator.py +0 -0
  271. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_project_config.py +0 -0
  272. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_projection_compile.py +0 -0
  273. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_render_helper_conformance.py +0 -0
  274. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_render_helper_generator.py +0 -0
  275. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_reverse_finders.py +0 -0
  276. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_router_autoset.py +0 -0
  277. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_router_generator.py +0 -0
  278. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_runner.py +0 -0
  279. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_source_resolution.py +0 -0
  280. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_sourceless_projection.py +0 -0
  281. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_template_data.py +0 -0
  282. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_template_generator.py +0 -0
  283. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_template_output_pattern.py +0 -0
  284. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_template_scope_helpers.py +0 -0
  285. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_template_scope_walk.py +0 -0
  286. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_template_spec.py +0 -0
  287. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_tph_codegen.py +0 -0
  288. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_trace_helper_generator.py +0 -0
  289. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_type_map.py +0 -0
  290. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_validation_conformance.py +0 -0
  291. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/codegen/test_write_through.py +0 -0
  292. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/config/__init__.py +0 -0
  293. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/config/test_dependencies.py +0 -0
  294. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/config/test_library_package_guard.py +0 -0
  295. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/config/test_neutral_config.py +0 -0
  296. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/config/test_source_resolver.py +0 -0
  297. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/__init__.py +0 -0
  298. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/capabilities.py +0 -0
  299. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/conformance-expected-failures.json +0 -0
  300. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/conformance_adapter.py +0 -0
  301. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/corpus.py +0 -0
  302. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/expected_failures.py +0 -0
  303. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/fixture_discovery.py +0 -0
  304. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/navigator.py +0 -0
  305. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
  306. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_conformance.py +0 -0
  307. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_dependency_conformance.py +0 -0
  308. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_extract_conformance.py +0 -0
  309. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_extract_object_verdict.py +0 -0
  310. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_fr010_loader_attrs.py +0 -0
  311. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_fr011_attrs.py +0 -0
  312. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_generator_registry_conformance.py +0 -0
  313. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_object_model_conformance.py +0 -0
  314. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_provider_composition_conformance.py +0 -0
  315. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_registry_conformance.py +0 -0
  316. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_runner_hardfail.py +0 -0
  317. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_scope_conformance.py +0 -0
  318. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_source_resolution_conformance.py +0 -0
  319. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_spec_metamodel_embed.py +0 -0
  320. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_strict_attr_load.py +0 -0
  321. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_template_codegen_conformance.py +0 -0
  322. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_template_generator_conformance.py +0 -0
  323. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/test_yaml_conformance.py +0 -0
  324. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
  325. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/__init__.py +0 -0
  326. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/api_contract_assertions.py +0 -0
  327. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/api_contract_jsonb_server.py +0 -0
  328. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/api_contract_m2m_server.py +0 -0
  329. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/api_contract_server.py +0 -0
  330. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/generated_jsonb_app.py +0 -0
  331. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/generated_m2m_app.py +0 -0
  332. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/generated_router_app.py +0 -0
  333. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/generated_tph_app.py +0 -0
  334. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/meta_ai_trace.yaml +0 -0
  335. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/normalization.py +0 -0
  336. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/postgres_container.py +0 -0
  337. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/query_runner.py +0 -0
  338. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/scenarios.py +0 -0
  339. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_api_contract.py +0 -0
  340. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_api_contract_generated.py +0 -0
  341. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_api_contract_jsonb.py +0 -0
  342. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_api_contract_m2m.py +0 -0
  343. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_api_contract_m2m_generated.py +0 -0
  344. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_api_contract_tph_generated.py +0 -0
  345. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_generated_router_uuid_pk.py +0 -0
  346. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_llm_call_trace.py +0 -0
  347. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_normalization.py +0 -0
  348. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_query_scenarios.py +0 -0
  349. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/integration/test_runtime_return_types.py +0 -0
  350. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/loader/__init__.py +0 -0
  351. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/loader/test_abstract_subtype_authored.py +0 -0
  352. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/loader/test_enum_extends_values_conflict.py +0 -0
  353. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/loader/test_field_mutability_order.py +0 -0
  354. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/loader/test_shipped_library_ai.py +0 -0
  355. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/loader/test_template_payload_target_210.py +0 -0
  356. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/open_closed_proof_test.py +0 -0
  357. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/__init__.py +0 -0
  358. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/__init__.py +0 -0
  359. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_coerce.py +0 -0
  360. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_extract.py +0 -0
  361. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_extract_map.py +0 -0
  362. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_json_forgiving_reader.py +0 -0
  363. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_locate.py +0 -0
  364. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_model.py +0 -0
  365. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_normalize.py +0 -0
  366. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_strip.py +0 -0
  367. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
  368. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/prompt/__init__.py +0 -0
  369. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/prompt/test_output_format_renderer.py +0 -0
  370. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/test_email_document.py +0 -0
  371. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/test_filesystem_provider.py +0 -0
  372. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/test_output_format_renderer_nested.py +0 -0
  373. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/test_output_prompt_conformance.py +0 -0
  374. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/test_render_conformance.py +0 -0
  375. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/test_render_max_chars.py +0 -0
  376. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/test_verify.py +0 -0
  377. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/render/test_verify_conformance.py +0 -0
  378. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/runtime/test_object_manager_enum_intvaluemap.py +0 -0
  379. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/runtime/test_object_manager_table_name.py +0 -0
  380. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/source/__init__.py +0 -0
  381. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/source/test_fr5c_merge_attribution.py +0 -0
  382. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/source/test_fr5d_reference_resolution.py +0 -0
  383. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/source/test_fr5e_database_source_shape.py +0 -0
  384. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/source/test_json_path.py +0 -0
  385. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/source/test_semantic_diff.py +0 -0
  386. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/source/test_source_on_node.py +0 -0
  387. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/source/test_yaml_positions.py +0 -0
  388. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/test_api_docs_accuracy.py +0 -0
  389. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/__init__.py +0 -0
  390. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_agent_context_staleness.py +0 -0
  391. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_capabilities.py +0 -0
  392. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_column_naming_strategy.py +0 -0
  393. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_common_attrs.py +0 -0
  394. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_core_types.py +0 -0
  395. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_derive_m2m_declaring_entity.py +0 -0
  396. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_effective_children_sibling_shadowing.py +0 -0
  397. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_effective_package.py +0 -0
  398. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_errors.py +0 -0
  399. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_field_enum.py +0 -0
  400. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_field_enum_intvaluemap.py +0 -0
  401. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_field_map_validation.py +0 -0
  402. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
  403. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_file_source_id.py +0 -0
  404. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
  405. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_index_lookup.py +0 -0
  406. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_llm_recorder.py +0 -0
  407. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_loader.py +0 -0
  408. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_loader_bom.py +0 -0
  409. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_loader_class.py +0 -0
  410. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_merge.py +0 -0
  411. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_meta_attr.py +0 -0
  412. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_meta_data.py +0 -0
  413. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_meta_source.py +0 -0
  414. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_module_shortcuts.py +0 -0
  415. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_n2m_resolver.py +0 -0
  416. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_n2m_resolver_inherited.py +0 -0
  417. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_no_dead_config_fields.py +0 -0
  418. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
  419. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
  420. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_object_manager_write_through.py +0 -0
  421. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_one_primary_source.py +0 -0
  422. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_parser.py +0 -0
  423. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_parser_yaml.py +0 -0
  424. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_provider.py +0 -0
  425. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_provider_extension.py +0 -0
  426. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_registry.py +0 -0
  427. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_registry_completeness.py +0 -0
  428. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_registry_extend.py +0 -0
  429. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_registry_sealed.py +0 -0
  430. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_relationship_m2m_validation.py +0 -0
  431. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_relationship_references.py +0 -0
  432. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_relationship_referential_actions.py +0 -0
  433. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_resolution_key.py +0 -0
  434. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
  435. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_serializer.py +0 -0
  436. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_serializer_shared_document.py +0 -0
  437. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_shared_constants.py +0 -0
  438. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_smoke.py +0 -0
  439. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_source_escapes.py +0 -0
  440. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_sources.py +0 -0
  441. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_strict_child_placement.py +0 -0
  442. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_super_resolve.py +0 -0
  443. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_template_toolcall.py +0 -0
  444. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
  445. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_validation_attr_schema.py +0 -0
  446. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_validation_filter_values.py +0 -0
  447. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_validation_origin_195.py +0 -0
  448. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_validation_origin_paths.py +0 -0
  449. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_validation_sort_field.py +0 -0
  450. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_validation_warnings.py +0 -0
  451. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_write_coercion_arrays.py +0 -0
  452. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/tests/unit/test_yaml_desugar.py +0 -0
  453. {metaobjects-1.0.4 → metaobjects-1.0.5rc1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: metaobjects
3
- Version: 1.0.4
3
+ Version: 1.0.5rc1
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.4"
3
+ version = "1.0.5rc1"
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"
@@ -11,7 +11,7 @@ EMBEDDED_LIBRARY: dict[str, str] = {
11
11
  'ai/model': '# library/ai/model.yaml — the CORE layer: the LLM-call trace envelope.\n#\n# Adopters opt in via `libraries: ["ai"]`, then `extends: "metaobjects::ai::LlmCallBase"`.\n#\n# This layer declares NO `source.rdb`, so opting into `"ai"` alone adds zero tables and\n# zero generated code — the design is present and resolvable, and nothing else happens\n# until the adopter adds `"ai/db"`. See library/iam/model.yaml for the full rationale.\n#\n# This file was split out of the former `library/ai/llm-call.yaml`, which shipped the\n# abstract base and a concrete `LlmCall` carrying `source.rdb` together. That was\n# recorded as an accepted wart on the grounds that splitting would change what existing\n# `ai` adopters get; a sweep of the estate found there are none, so it was closed rather\n# than documented (FR-043 Amendment 1).\nmetadata:\n package: metaobjects::ai\n children:\n - object.entity:\n name: LlmCallBase\n abstract: true\n children:\n - field.uuid: { name: traceId }\n - field.uuid: { name: spanId }\n - field.uuid: { name: parentSpanId }\n - field.string: { name: sessionId }\n - field.string: { name: callType }\n - field.string: { name: system }\n - field.string: { name: requestModel }\n - field.string: { name: responseModel }\n - field.int: { name: inputTokens }\n - field.int: { name: outputTokens }\n - field.currency: { name: costMinor, currency: USD }\n - field.int: { name: latencyMs }\n - field.string: { name: finishReason }\n - field.string: { name: status }\n - field.string: { name: errorDetail }\n - field.timestamp: { name: startedAt }\n - field.string: { name: llmRequest, dbColumnType: jsonb } # generic jsonb (no objectRef)\n - field.string: { name: llmResponse, dbColumnType: jsonb }\n - object.entity:\n name: LlmCall\n extends: metaobjects::ai::LlmCallBase\n description: The concrete trace row. Its `source.rdb` lives in db.yaml, so opting into the core layer alone declares the shape without proposing a table.\n children:\n - identity.primary: { name: id, fields: ["spanId"] }\n',
12
12
  'ai/requirements': "# library/ai/requirements.yaml — what the LLM-call trace envelope PROMISES.\n#\n# A RETROFIT, not new design: llm-call.yaml landed 2026-06-03 and `requirement.functional`\n# first appears 2026-08-11, so the library could not have carried requirements when it was\n# written. That is why this file is worth reading as a worked example — it shows what\n# declaring the design of something that already exists actually turns up.\n#\n# The entry that earns its keep is `typedIo`, honestly `partial` + `accepted`: the library\n# declares the ENVELOPE and the adopter declares the typed VO columns. Recording that seam\n# in the ledger is where an agent meets it, before adding a fourth trace column.\n#\n# HIERARCHY IS NESTING, and the L4/L5 split is grain. An L4 names the OBJECT it is about;\n# the fields that carry it hang off it as an L5 child. Writing the fields at L4 is\n# ERR_REQUIREMENT_L4_NOT_OBJECT, and writing the concerns as SIBLINGS of the L2 leaves the\n# L2 claiming nothing — both of which this file did until the standalone verify gate\n# existed (`cli/test/shipped-library-verify.test.ts`).\nmetadata:\n package: metaobjects::ai\n children:\n - requirement.functional:\n name: llmTracing\n level: 2\n status: live\n statement: Every call to a language model leaves a row that says what was asked, what came back, what it cost and how long it took.\n counterexample: A spend figure nobody can attribute to a call.\n description: The segment this library covers. Its three children below are the concerns it decomposes into.\n children:\n - requirement.functional:\n name: envelope\n level: 4\n status: live\n statement: A trace row identifies its call and its place in a trace — trace, span, parent span, session, call type, system.\n counterexample: A log line that cannot be joined to the request that produced it.\n implementedBy: [LlmCallBase]\n children:\n - requirement.functional:\n name: traceAddressing\n level: 5\n status: live\n statement: The four addressing columns are declared on the base — trace, span, parent span and session.\n counterexample: A row whose place in a trace is inferred from insertion order.\n description: >-\n The member grain exists here so the claim RESOLVES against the fields\n themselves: renaming or dropping one of them dangles this reference and\n fails the build, which naming the object alone would not.\n implementedBy: [LlmCallBase.traceId, LlmCallBase.spanId, LlmCallBase.parentSpanId, LlmCallBase.sessionId]\n\n - requirement.functional:\n name: accounting\n level: 4\n status: live\n statement: A trace row carries the tokens in, the tokens out, and the cost in integer minor units.\n counterexample: A cost stored as a float.\n description: >-\n `field.currency` — integer minor units on the wire, always. Float arithmetic for\n money is forbidden by the cross-port wire contract, and a spend total is exactly\n the sum that exposes it.\n implementedBy: [LlmCallBase]\n children:\n - requirement.functional:\n name: tokenAndCostColumns\n level: 5\n status: live\n statement: Tokens in, tokens out and cost are three declared columns, the cost a field.currency.\n counterexample: A cost column declared as a double.\n implementedBy: [LlmCallBase.inputTokens, LlmCallBase.outputTokens, LlmCallBase.costMinor]\n\n - requirement.functional:\n name: typedIo\n level: 4\n status: partial\n disposition: accepted\n statement: The request and response bodies are stored as structured jsonb, not as opaque text.\n counterexample: A prompt stored as a string nobody can query a field out of.\n notes: >-\n The library declares the two columns as generic jsonb with no `@objectRef`,\n because it cannot know the adopter's request/response shape. Typing them is the\n ADOPTER's move: declare an `object.value` and overlay the field with\n `@objectRef` + `@storage: jsonb`. This is the seam ADR-0024 drew, recorded here\n rather than in prose so it is in the ledger an agent reads before adding a\n fourth trace column of its own.\n implementedBy: [LlmCallBase]\n children:\n - requirement.functional:\n name: jsonbBodies\n level: 5\n status: live\n statement: The request and response bodies are declared as jsonb columns on the base.\n counterexample: A prompt stored in a text column.\n description: >-\n `live` where its parent is `partial`, and the split is the point: the\n COLUMNS are shipped and this claim is fully realised; what is outstanding\n is the TYPING of them, which is the parent's gap and the adopter's move.\n implementedBy: [LlmCallBase.llmRequest, LlmCallBase.llmResponse]\n\n - requirement.architectural:\n name: traceRowsCarryTiming\n status: live\n statement: Every trace row records when the call started and how long it took.\n counterexample: A latency figure derived from log timestamps after the fact.\n description: >-\n Architectural, so it propagates down `extends` to every adopter entity deriving\n from LlmCallBase — which is the point: an adopter's own trace table is claimed\n by this requirement for free, and dropping the columns breaks the build.\n implementedBy: [LlmCallBase]\n\n - requirement.architectural:\n name: traceRowsCarryOutcome\n status: live\n statement: Every trace row records how the call ended — a status, a finish reason, and the error detail when there was one.\n counterexample: A failed call indistinguishable from one that never happened.\n implementedBy: [LlmCallBase]\n",
13
13
  'iam/db': '# library/iam/db.yaml — the DB PERSISTENCE layer for metaobjects::iam.\n#\n# Opted into as `"iam/db"`, which IMPLIES `"iam"`: this file is nothing but\n# `overlay: true` redeclarations, and an overlay whose target was never declared is\n# ERR_OVERLAY_NO_TARGET.\n#\n# It carries exactly two kinds of child — `source.rdb` and `index.lookup` — and nothing\n# else. The field set, the identities and the relationships all live in model.yaml,\n# because they are the DESIGN; what lives here is where the rows go and which lookups are\n# worth an index. Add a field here and the core layer stops being the whole model, which\n# is the thing the split exists to guarantee.\n#\n# Physical names are `iam_`-prefixed. Two reasons, both real: `user` and `group` are\n# reserved words in Postgres, and an adopter very likely has tables of their own by those\n# names. A library that collides on a table name is a library nobody can adopt.\nmetadata:\n package: metaobjects::iam\n children:\n - object.entity:\n name: User\n overlay: true\n children:\n - source.rdb: { table: iam_user, role: primary }\n\n - object.entity:\n name: GroupType\n overlay: true\n children:\n - source.rdb: { table: iam_group_type, role: primary }\n\n - object.entity:\n name: Group\n overlay: true\n children:\n - source.rdb: { table: iam_group, role: primary }\n # Nesting is walked parent-ward constantly; the FK alone gives no index.\n - index.lookup: { name: ixParent, fields: [parentId] }\n\n - object.entity:\n name: Role\n overlay: true\n children:\n - source.rdb: { table: iam_role, role: primary }\n\n - object.entity:\n name: Permission\n overlay: true\n children:\n - source.rdb: { table: iam_permission, role: primary }\n\n - object.entity:\n name: GroupMember\n overlay: true\n children:\n - source.rdb: { table: iam_group_member, role: primary }\n # The composite PK covers (userId, groupId), so "who is in this group?" —\n # the other direction — has no index without this one. Same reasoning for\n # every ixSecond below.\n - index.lookup: { name: ixGroup, fields: [groupId] }\n\n - object.entity:\n name: RolePermission\n overlay: true\n children:\n - source.rdb: { table: iam_role_permission, role: primary }\n - index.lookup: { name: ixPermission, fields: [permissionId] }\n\n - object.entity:\n name: UserRole\n overlay: true\n children:\n - source.rdb: { table: iam_user_role, role: primary }\n - index.lookup: { name: ixRole, fields: [roleId] }\n\n - object.entity:\n name: GroupMemberRole\n overlay: true\n children:\n - source.rdb: { table: iam_group_member_role, role: primary }\n # "who holds this role in this group?" — the scoped-grant read.\n - index.lookup: { name: ixGroupRole, fields: [groupId, roleId] }\n',
14
- 'iam/model': '# library/iam/model.yaml — the CORE layer: identity and access management.\n#\n# Adopters opt in via `libraries: ["iam"]` in .metaobjects/config.json.\n#\n# This layer declares NO `source.rdb`, and that is the whole point of the split. A\n# sourceless object is inert by a contract that already ships: migrate skips an object\n# with no writable source, and codegen emits no route, queries, hooks, grid or form for\n# one (both citing #248 — persistability derives from source presence, never from the\n# object subtype). It still gets a type-only interface, so `extends` and reference work.\n#\n# So `libraries: ["iam"]` adds ZERO tables and ZERO generated code. What an adopter gains\n# is the design being present and resolvable: an agent working in the repo knows the\n# capability exists and can draw on it, and nothing else happens until the adopter adds\n# `"iam/db"`.\n#\n# Authoring discipline (FR-043 §3.1), so the departures are visible:\n# - `field.uuid` + `generation: uuid` on principals; composite ASSIGNED keys on\n# junctions. Never `increment` — a library cannot know the adopter\'s id strategy.\n# - Physical names carry the `iam_` prefix (in db.yaml): `user` and `group` are\n# reserved words in Postgres, and an adopter has tables of their own.\n# - No adopter-facing profile data. That arrives by `overlay: true`.\n# - No credentials. See requirements.yaml → `noCredentialsOnUser`.\nmetadata:\n package: metaobjects::iam\n children:\n - object.entity:\n name: IamBase\n abstract: true\n description: Shared shape of every iam principal and definition — a stable uuid plus change timestamps. Junctions do not extend it; they are addressed by their participants.\n children:\n - field.uuid: { name: id, required: true }\n - field.timestamp: { name: createdAt, autoSet: onCreate }\n - field.timestamp: { name: updatedAt, autoSet: onUpdate }\n\n - object.entity:\n name: User\n extends: IamBase\n description: A person or service account that can be granted access. Carries no authentication secret of any kind — see the noCredentialsOnUser requirement.\n children:\n - field.string: { name: username, required: true, maxLength: 64, filterable: true }\n - field.string: { name: email, required: true, maxLength: 254, stringFormat: email, filterable: true }\n - field.string: { name: displayName, maxLength: 120 }\n # NOT `filterable: true`, deliberately. The loader warns when a filterable\n # field is in no identity — filtering on it sequential-scans — and a library\n # must not ship a warning to every adopter. `username` and `email` carry it\n # because they have identity.secondary; `status` does not. An adopter who\n # wants to filter on status overlays `filterable` AND an index together,\n # which is exactly what the layer split is for.\n - field.enum: { name: status, required: true, values: [invited, active, suspended, closed], default: active }\n - field.timestamp: { name: emailVerifiedAt }\n - field.timestamp: { name: lastSeenAt }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqUsername, fields: [username] }\n - identity.secondary: { name: uqEmail, fields: [email] }\n - relationship.association: { name: groups, objectRef: Group, cardinality: many, through: GroupMember }\n - relationship.association: { name: roles, objectRef: Role, cardinality: many, through: UserRole }\n\n - object.entity:\n name: GroupType\n extends: IamBase\n description: What KIND of group this is — a team, a tenant, a project. An entity rather than an enum, because "which roles may be held in this kind of group" is data an adopter extends, and an enum\'s values cannot be extended by overlay.\n children:\n - field.string: { name: key, required: true, maxLength: 64 }\n - field.string: { name: name, required: true, maxLength: 120 }\n - field.string: { name: description, maxLength: 500 }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqKey, fields: [key] }\n\n - object.entity:\n name: Group\n extends: IamBase\n description: A nestable collection of users, of a declared GroupType. Nesting is by parentId; acyclicity is an invariant the schema cannot express — see the acyclicGroupNesting requirement.\n children:\n - field.uuid: { name: groupTypeId, required: true }\n - field.uuid: { name: parentId }\n - field.string: { name: key, required: true, maxLength: 64 }\n # Not filterable for the same reason as User.status above.\n - field.string: { name: name, required: true, maxLength: 120 }\n - field.string: { name: description, maxLength: 500 }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqKey, fields: [key] }\n - identity.reference: { name: fkGroupType, fields: [groupTypeId], references: GroupType, onDelete: restrict }\n - identity.reference: { name: fkParent, fields: [parentId], references: Group, onDelete: restrict }\n\n - object.entity:\n name: Role\n extends: IamBase\n description: A reusable bundle of permissions. Code never compares a role NAME to a literal — it asks whether a user holds a permission, and the mapping is data.\n children:\n - field.string: { name: key, required: true, maxLength: 64 }\n - field.string: { name: name, required: true, maxLength: 120 }\n - field.string: { name: description, maxLength: 500 }\n - field.uuid: { name: groupTypeId, description: "When set, this role may be held only within groups of this type; absent means grantable anywhere." }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqKey, fields: [key] }\n - identity.reference: { name: fkGroupType, fields: [groupTypeId], references: GroupType, onDelete: restrict }\n - relationship.association: { name: permissions, objectRef: Permission, cardinality: many, through: RolePermission }\n\n - object.entity:\n name: Permission\n extends: IamBase\n description: "The assignable unit — a stable <resource>:<action> key the application checks against. An entity, not an enum, on ADR-0037\'s own reasoning: it has its own identity, its own lifecycle, and a junction with real foreign keys."\n children:\n - field.string: { name: key, required: true, maxLength: 128, description: "Stable <resource>:<action> key the application checks against." }\n - field.string: { name: description, maxLength: 500 }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqKey, fields: [key] }\n\n # ---- grant surface: every grant is a row, addressed by its participants ----\n #\n # Junctions do NOT extend IamBase: they have no identity of their own, and adding a\n # surrogate uuid to a row whose identity IS its participants invites a duplicate.\n\n - object.entity:\n name: GroupMember\n description: A user\'s membership of a group.\n children:\n - field.uuid: { name: userId, required: true }\n - field.uuid: { name: groupId, required: true }\n - field.timestamp: { name: joinedAt, autoSet: onCreate }\n - identity.primary: { name: pk, fields: [userId, groupId], generation: assigned }\n - identity.reference: { name: fkUser, fields: [userId], references: User, onDelete: cascade }\n - identity.reference: { name: fkGroup, fields: [groupId], references: Group, onDelete: cascade }\n\n - object.entity:\n name: RolePermission\n description: A permission granted by a role.\n children:\n - field.uuid: { name: roleId, required: true }\n - field.uuid: { name: permissionId, required: true }\n - identity.primary: { name: pk, fields: [roleId, permissionId], generation: assigned }\n - identity.reference: { name: fkRole, fields: [roleId], references: Role, onDelete: cascade }\n - identity.reference: { name: fkPermission, fields: [permissionId], references: Permission, onDelete: restrict }\n\n - object.entity:\n name: UserRole\n description: A system-wide grant of a role to a user.\n children:\n - field.uuid: { name: userId, required: true }\n - field.uuid: { name: roleId, required: true }\n - field.timestamp: { name: grantedAt, autoSet: onCreate }\n - identity.primary: { name: pk, fields: [userId, roleId], generation: assigned }\n - identity.reference: { name: fkUser, fields: [userId], references: User, onDelete: cascade }\n - identity.reference: { name: fkRole, fields: [roleId], references: Role, onDelete: restrict }\n\n - object.entity:\n name: GroupMemberRole\n description: A grant of a role to a user WITHIN one group. Three foreign keys, so it is not an M:N @through junction (which must declare exactly two identity.reference children); it is read by explicit finders.\n children:\n - field.uuid: { name: userId, required: true }\n - field.uuid: { name: groupId, required: true }\n - field.uuid: { name: roleId, required: true }\n - field.timestamp: { name: grantedAt, autoSet: onCreate }\n - identity.primary: { name: pk, fields: [userId, groupId, roleId], generation: assigned }\n - identity.reference: { name: fkUser, fields: [userId], references: User, onDelete: cascade }\n - identity.reference: { name: fkGroup, fields: [groupId], references: Group, onDelete: cascade }\n - identity.reference: { name: fkRole, fields: [roleId], references: Role, onDelete: restrict }\n',
14
+ 'iam/model': '# library/iam/model.yaml — the CORE layer: identity and access management.\n#\n# Adopters opt in via `libraries: ["iam"]` in .metaobjects/config.json.\n#\n# This layer declares NO `source.rdb`, and that is the whole point of the split. A\n# sourceless object is inert by a contract that already ships: migrate skips an object\n# with no writable source, and codegen emits no route, queries, hooks, grid or form for\n# one (both citing #248 — persistability derives from source presence, never from the\n# object subtype). It still gets a type-only interface, so `extends` and reference work.\n#\n# So `libraries: ["iam"]` adds ZERO tables and ZERO generated code. What an adopter gains\n# is the design being present and resolvable: an agent working in the repo knows the\n# capability exists and can draw on it, and nothing else happens until the adopter adds\n# `"iam/db"`.\n#\n# Authoring discipline (FR-043 §3.1), so the departures are visible:\n# - `field.uuid` + `generation: uuid` on principals; composite ASSIGNED keys on\n# junctions. Never `increment` — a library cannot know the adopter\'s id strategy.\n# - Physical names carry the `iam_` prefix (in db.yaml): `user` and `group` are\n# reserved words in Postgres, and an adopter has tables of their own.\n# - No adopter-facing profile data. That arrives by `overlay: true`.\n# - No credentials. See requirements.yaml → `noCredentialsOnUser`.\nmetadata:\n package: metaobjects::iam\n children:\n - object.entity:\n name: IamBase\n abstract: true\n description: Shared shape of every iam principal and definition — a stable uuid plus change timestamps. Junctions do not extend it; they are addressed by their participants.\n children:\n - field.uuid: { name: id, required: true }\n - field.timestamp: { name: createdAt, autoSet: onCreate }\n - field.timestamp: { name: updatedAt, autoSet: onUpdate }\n\n - object.entity:\n name: User\n extends: IamBase\n description: A person or service account that can be granted access. Carries no authentication secret of any kind — see the noCredentialsOnUser requirement.\n children:\n - field.string: { name: username, required: true, maxLength: 64, filterable: true }\n - field.string: { name: email, required: true, maxLength: 254, stringFormat: email, filterable: true }\n - field.string: { name: displayName, maxLength: 120 }\n # NOT `filterable: true`, deliberately. The loader warns when a filterable\n # field is in no identity — filtering on it sequential-scans — and a library\n # must not ship a warning to every adopter. `username` and `email` carry it\n # because they have identity.secondary; `status` does not. An adopter who\n # wants to filter on status overlays `filterable` AND an index together,\n # which is exactly what the layer split is for.\n - field.enum: { name: status, required: true, values: [invited, active, suspended, closed], default: active }\n - field.timestamp: { name: emailVerifiedAt }\n - field.timestamp: { name: lastSeenAt }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqUsername, fields: [username] }\n - identity.secondary: { name: uqEmail, fields: [email] }\n - relationship.association: { name: groups, objectRef: Group, cardinality: many, through: GroupMember }\n - relationship.association: { name: roles, objectRef: Role, cardinality: many, through: UserRole }\n\n - object.entity:\n name: GroupType\n extends: IamBase\n description: What KIND of group this is — a team, a tenant, a project. An entity rather than an enum, because "which roles may be held in this kind of group" is data an adopter extends, and an enum\'s values cannot be extended by overlay.\n children:\n - field.string: { name: key, required: true, maxLength: 64 }\n - field.string: { name: name, required: true, maxLength: 120 }\n - field.string: { name: description, maxLength: 500 }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqGroupTypeKey, fields: [key] }\n\n - object.entity:\n name: Group\n extends: IamBase\n description: A nestable collection of users, of a declared GroupType. Nesting is by parentId; acyclicity is an invariant the schema cannot express — see the acyclicGroupNesting requirement.\n children:\n - field.uuid: { name: groupTypeId, required: true }\n - field.uuid: { name: parentId }\n - field.string: { name: key, required: true, maxLength: 64 }\n # Not filterable for the same reason as User.status above.\n - field.string: { name: name, required: true, maxLength: 120 }\n - field.string: { name: description, maxLength: 500 }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqGroupKey, fields: [key] }\n - identity.reference: { name: fkGroupType, fields: [groupTypeId], references: GroupType, onDelete: restrict }\n - identity.reference: { name: fkParent, fields: [parentId], references: Group, onDelete: restrict }\n\n - object.entity:\n name: Role\n extends: IamBase\n description: A reusable bundle of permissions. Code never compares a role NAME to a literal — it asks whether a user holds a permission, and the mapping is data.\n children:\n - field.string: { name: key, required: true, maxLength: 64 }\n - field.string: { name: name, required: true, maxLength: 120 }\n - field.string: { name: description, maxLength: 500 }\n - field.uuid: { name: groupTypeId, description: "When set, this role may be held only within groups of this type; absent means grantable anywhere." }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqRoleKey, fields: [key] }\n - identity.reference: { name: fkGroupType, fields: [groupTypeId], references: GroupType, onDelete: restrict }\n - relationship.association: { name: permissions, objectRef: Permission, cardinality: many, through: RolePermission }\n\n - object.entity:\n name: Permission\n extends: IamBase\n description: "The assignable unit — a stable <resource>:<action> key the application checks against. An entity, not an enum, on ADR-0037\'s own reasoning: it has its own identity, its own lifecycle, and a junction with real foreign keys."\n children:\n - field.string: { name: key, required: true, maxLength: 128, description: "Stable <resource>:<action> key the application checks against." }\n - field.string: { name: description, maxLength: 500 }\n - identity.primary: { name: pk, fields: [id], generation: uuid }\n - identity.secondary: { name: uqPermissionKey, fields: [key] }\n\n # ---- grant surface: every grant is a row, addressed by its participants ----\n #\n # Junctions do NOT extend IamBase: they have no identity of their own, and adding a\n # surrogate uuid to a row whose identity IS its participants invites a duplicate.\n\n - object.entity:\n name: GroupMember\n description: A user\'s membership of a group.\n children:\n - field.uuid: { name: userId, required: true }\n - field.uuid: { name: groupId, required: true }\n - field.timestamp: { name: joinedAt, autoSet: onCreate }\n - identity.primary: { name: pk, fields: [userId, groupId], generation: assigned }\n - identity.reference: { name: fkUser, fields: [userId], references: User, onDelete: cascade }\n - identity.reference: { name: fkGroup, fields: [groupId], references: Group, onDelete: cascade }\n\n - object.entity:\n name: RolePermission\n description: A permission granted by a role.\n children:\n - field.uuid: { name: roleId, required: true }\n - field.uuid: { name: permissionId, required: true }\n - identity.primary: { name: pk, fields: [roleId, permissionId], generation: assigned }\n - identity.reference: { name: fkRole, fields: [roleId], references: Role, onDelete: cascade }\n - identity.reference: { name: fkPermission, fields: [permissionId], references: Permission, onDelete: restrict }\n\n - object.entity:\n name: UserRole\n description: A system-wide grant of a role to a user.\n children:\n - field.uuid: { name: userId, required: true }\n - field.uuid: { name: roleId, required: true }\n - field.timestamp: { name: grantedAt, autoSet: onCreate }\n - identity.primary: { name: pk, fields: [userId, roleId], generation: assigned }\n - identity.reference: { name: fkUser, fields: [userId], references: User, onDelete: cascade }\n - identity.reference: { name: fkRole, fields: [roleId], references: Role, onDelete: restrict }\n\n - object.entity:\n name: GroupMemberRole\n description: A grant of a role to a user WITHIN one group. Three foreign keys, so it is not an M:N @through junction (which must declare exactly two identity.reference children); it is read by explicit finders.\n children:\n - field.uuid: { name: userId, required: true }\n - field.uuid: { name: groupId, required: true }\n - field.uuid: { name: roleId, required: true }\n - field.timestamp: { name: grantedAt, autoSet: onCreate }\n - identity.primary: { name: pk, fields: [userId, groupId, roleId], generation: assigned }\n - identity.reference: { name: fkUser, fields: [userId], references: User, onDelete: cascade }\n - identity.reference: { name: fkGroup, fields: [groupId], references: Group, onDelete: cascade }\n - identity.reference: { name: fkRole, fields: [roleId], references: Role, onDelete: restrict }\n',
15
15
  'iam/requirements': '# library/iam/requirements.yaml — what this library\'s design PROMISES.\n#\n# This is what makes iam a library rather than a schema snippet. Without requirements an\n# adopter gets nine tables; with them they get nine tables plus a build that is held to\n# "no authorization decision is hard-wired to a name", which no snippet can do.\n#\n# Two reading rules, both load-bearing:\n#\n# `live` here means "the model AS SHIPPED realises this" — never "your application\n# does". A ledger binds to model nodes; runtime guarantees are the runtime\'s tests, and\n# this library does not invent a way to point a requirement at code (@verifiedBy was\n# retired for exactly that). Behaviour the model cannot carry ships as `partial` +\n# `disposition: accepted` with a notes sentence naming what the adopter must do.\n#\n# The functional tree roots at L2, not L1. L1 is the adopter\'s SOLUTION, and a library\n# is by definition a segment of someone else\'s. Architectural claims ship flat.\n#\n# HIERARCHY IS NESTING, and the L4/L5 split is grain. The concerns are CHILDREN of the L2\n# rather than its siblings, and an L4 names the OBJECT it is about while the field that\n# carries it hangs off it as an L5 child. Written flat, the L2 claims nothing in its whole\n# subtree; written at L4, a field reference is ERR_REQUIREMENT_L4_NOT_OBJECT. Both shipped\n# here until the standalone verify gate existed (`cli/test/shipped-library-verify.test.ts`).\nmetadata:\n package: metaobjects::iam\n children:\n # ---- functional: the L2 segment and the concerns nested under it --------\n - requirement.functional:\n name: accessControl\n level: 2\n status: live\n statement: Who may do what is answered from stored grants, never from a name compared to a literal in code.\n counterexample: A branch that reads `if (user.role === "admin")`.\n description: The segment this library covers. The concerns beneath it are what it decomposes into.\n children:\n - requirement.functional:\n name: identity\n level: 4\n status: live\n statement: A person or service account is represented once, addressed by a uuid, and reachable by username or email.\n counterexample: Two rows for the same person because the email changed.\n implementedBy: [User]\n\n - requirement.functional:\n name: grouping\n level: 4\n status: live\n statement: Users are collected into typed, nestable groups, and the kind of group is data rather than a hard-coded set.\n counterexample: A `teamOrTenant` boolean.\n implementedBy: [Group, GroupType, GroupMember]\n\n - requirement.functional:\n name: acyclicGroupNesting\n level: 4\n status: partial\n disposition: accepted\n statement: A group is never its own ancestor.\n counterexample: Two groups each naming the other as parent.\n notes: >-\n The schema cannot express this — a self-referencing FK admits a cycle, and the\n only relational forms that would catch it (a recursive CHECK, a closure table\n maintained by trigger) are DB-specific and would not survive three dialects.\n The adopter enforces it where the write happens. Recorded rather than omitted\n so an agent reading the ledger before adding a parent-setting endpoint sees the\n obligation.\n implementedBy: [Group]\n\n - requirement.functional:\n name: grants\n level: 4\n status: live\n statement: A role is granted to a user either system-wide or scoped to one group, and both are ordinary rows.\n counterexample: A nullable `groupId` on one grant table, where NULL means "everywhere".\n description: >-\n Two junctions, not one with a nullable scope. A NULL in a unique key is DISTINCT\n from every other NULL in SQL, so a nullable-scope design lets the same global\n grant be inserted twice; the fix needs a partial index whose expression carries\n a physical column name. Two composite-keyed tables need no escape hatch and\n survive three dialects and five ports unchanged.\n implementedBy: [UserRole, GroupMemberRole]\n\n - requirement.functional:\n name: roleScopedToGroupType\n level: 4\n status: partial\n disposition: accepted\n statement: A role bound to a group type is granted only within groups of that type.\n counterexample: A "tenant admin" role granted inside a project group.\n notes: >-\n Expressing this relationally needs the grant row to carry the group\'s type and\n a composite FK back to (group, type) — three foreign keys deep, unverified\n across five ports\' DDL and ORM paths. The adopter checks it at the point of\n grant. The declared half is the L5 child below; the enforcement is not.\n implementedBy: [Role, GroupMemberRole]\n children:\n - requirement.functional:\n name: roleDeclaresItsGroupType\n level: 5\n status: live\n statement: A role declares the group type it is bound to, as a nullable reference.\n counterexample: A role whose intended scope is recoverable only from its name.\n description: >-\n `live` where its parent is `partial`, and the split is grain as much as\n verdict: the DECLARATION is shipped and resolves against the field itself,\n so dropping the column fails the build — while the ENFORCEMENT, which no\n schema here can carry, stays the parent\'s accepted gap.\n implementedBy: [Role.groupTypeId]\n\n - requirement.functional:\n name: decision\n level: 4\n status: live\n statement: An authorization decision is the question "does this user hold this permission key", answered from rows.\n counterexample: A hard-coded list of usernames that bypass a check.\n implementedBy: [Permission, RolePermission]\n\n # ---- architectural: prohibitions in force --------------------------------\n\n - requirement.architectural:\n name: grantsAreRows\n status: live\n statement: A grant exists only as a stored row; nothing is granted by naming, position or convention.\n counterexample: A superuser recognised by username.\n implementedBy: [UserRole, GroupMemberRole, RolePermission, GroupMember]\n\n - requirement.architectural:\n name: noCredentialsOnUser\n status: live\n statement: A user row carries no authentication secret — no password, no hash, no knowledge-based question or answer.\n counterexample: A password or secret-answer column on the user table.\n description: >-\n Authentication is a separate capability with an entity per factor; this library\n is identity and authorization only.\n notes: >-\n This is the one thing every reader of a user table proposes adding, and a real\n legacy model of this shape stored a length-bounded plaintext password and a\n knowledge-based secret pair on the user row. Stating it as a prohibition IN\n FORCE — claimable, and rendered on agent/requirements.md — is what stops an\n agent extending "the user model" from re-deriving it on sight. It is\n `architectural`, not `retired`: retired is chartered for a capability built\n here and removed, and this library never built one.\n implementedBy: [User]\n\n - requirement.architectural:\n name: principalDeletionRevokesGrants\n status: live\n statement: Deleting a user or group removes its grants; deleting a role or permission still in use is refused.\n counterexample: A grant row pointing at a user who no longer exists.\n description: The referential rule in one sentence — cascade from a principal, restrict from a definition.\n implementedBy: [GroupMember, UserRole, GroupMemberRole, RolePermission]\n\n - requirement.architectural:\n name: stableIdentifiers\n status: live\n statement: Every principal and definition is addressed by a uuid that never changes; every grant by its participants.\n counterexample: A group referenced by its display name.\n implementedBy: [IamBase]\n',
16
16
  }
17
17
 
@@ -9,8 +9,10 @@ the loader like everything else — never hand-parsed from a side file.
9
9
  # ---------------------------------------------------------------------------
10
10
  # Subtypes — the axis is the CHECK POLARITY, a genuine behaviour difference and
11
11
  # therefore a subtype under ADR-0037 §2:
12
- # functional -> EXISTENCE: fails when nothing implements it
13
- # architectural -> UNIVERSALITY: fails when something violates it
12
+ # functional -> EXISTENCE: `meta verify` warns when nothing implements it,
13
+ # and fails when a node it names is gone
14
+ # architectural -> UNIVERSALITY: `meta verify` fails a live policy applied to nothing
15
+ # (it does not check that each claimed node complies)
14
16
  # ---------------------------------------------------------------------------
15
17
  REQUIREMENT_SUBTYPE_FUNCTIONAL = "functional"
16
18
  REQUIREMENT_SUBTYPE_ARCHITECTURAL = "architectural"
@@ -4,7 +4,7 @@
4
4
  {
5
5
  "type": "requirement",
6
6
  "subType": "functional",
7
- "description": "What the product does for a user, stated as one violable claim. Its check is EXISTENCE: it fails when nothing implements it. Hierarchy is nesting — an L1 solution contains its L2 segments, which contain L3 services, and so on down to the levels that reference the model.",
7
+ "description": "What the product does for a user, stated as one violable claim. Its check is EXISTENCE, run by `meta verify`: a live or partial claim with no implementing node anywhere in its subtree is a warning, and a named node that no longer exists is an error. Hierarchy is nesting — an L1 solution contains its L2 segments, which contain L3 services, and so on down to the levels that reference the model.",
8
8
  "whenToUse": "Something exists because someone asked for it. L1-L3 are levels of ABSTRACTION AND OWNERSHIP in the problem domain — whose need is this, and at what altitude — and are never a directory, package, deployable or module. Binding to technical constructs happens only at L4 (an object) and L5 (a member), which is the allocation step. Test every node: if a refactor that changes no behaviour would force it to move, its level is wrong.",
9
9
  "children": [
10
10
  {
@@ -96,7 +96,7 @@
96
96
  {
97
97
  "type": "requirement",
98
98
  "subType": "architectural",
99
- "description": "How the system is built, applied uniformly across the model. Its check is UNIVERSALITY: it fails when something VIOLATES it, which is the opposite polarity to a functional requirement. Flat by default and object-independent; it may optionally sit in a levelled tree when a quality taxonomy is being used to organise non-functional requirements.",
99
+ "description": "How the system is built, applied uniformly across the model. Its check is UNIVERSALITY, the opposite polarity to a functional requirement. What `meta verify` enforces is that a live or partial policy is applied at all — one claiming nothing is an error — not that each node it claims complies. Flat by default and object-independent; it may optionally sit in a levelled tree when a quality taxonomy is being used to organise non-functional requirements.",
100
100
  "whenToUse": "Something exists because every entity here looks like this — a uuid primary key, an @autoSet createdAt, a change-attribution column, tenant scoping. The discriminator is mechanical: did this exist because someone asked for something, or because it is the architecture? For a non-functional tree, an established quality taxonomy makes a good fixed upper structure (e.g. an ISO/IEC 25010 characteristic at L1, its sub-characteristic or a control-catalogue category at L2), with the model-binding claims at L4 and L5 as usual.",
101
101
  "children": [
102
102
  {
@@ -0,0 +1,156 @@
1
+ """CODEGEN-COMPILE CONFORMANCE (Python lane).
2
+
3
+ Generate from the SHARED cross-port corpus — ``fixtures/persistence-conformance/
4
+ canonical/meta.fitness.json`` — and prove every emitted module actually loads.
5
+
6
+ WHY THIS EXISTS. Four defects shipped in 1.0.4 that every existing gate was blind to,
7
+ because each one produced output that PARSES and GENERATES cleanly and only fails when
8
+ somebody builds it:
9
+
10
+ - a view over an int-backed enum imported a codec drizzle does not export (TS);
11
+ - a renamed projection field selected a column that does not exist (TS);
12
+ - a DbContext named FK config through ``nameof`` on a member that is not there (C#);
13
+ - an extract mapper did not compile for most scalar subtypes (Java).
14
+
15
+ ``metaobjects gen`` exits 0 in all four cases. The metamodel, render, persistence,
16
+ api-contract and registry corpora all stay green — they gate BEHAVIOR, and none of them
17
+ asks whether the emitted code builds. The adopter's build is the first thing that does,
18
+ which makes the adopter the gate. This closes that.
19
+
20
+ WHY TWO CHECKS, NOT ONE. Python has no static compiler, so the peer ports' single
21
+ "zero diagnostics" assertion has to be reconstructed from two halves, and neither half
22
+ alone is the gate:
23
+
24
+ 1. IMPORT the generated package. ``compile()`` alone only parses — it cannot tell a
25
+ name that does not exist from one that does. Importing runs each module's top level
26
+ for real, which is what resolves the package-relative imports the generators emit
27
+ BETWEEN modules; that cross-module agreement is the defect class the TS lane's
28
+ ``ts.createProgram`` catches and a per-file check structurally cannot.
29
+ 2. ``ruff check`` for undefined names. Importing only executes the module's top level,
30
+ so an undefined name inside a function body that nothing calls stays invisible.
31
+ F821 reads those branches statically. ruff is in the ``[dependency-groups] dev``
32
+ group ``uv run`` installs, so it is present wherever this test runs; mypy is NOT
33
+ (it is declared only under ``[project.optional-dependencies] dev``), which is why
34
+ this does not reach for it.
35
+
36
+ WHAT IT EXCLUDES: the ``routes`` generator, whose output imports FastAPI. Every peer
37
+ port draws the same line for the same reason (TS omits routesFile, C# omits
38
+ RoutesGenerator, Java omits SpringControllerGenerator) — the framework tier is proven by
39
+ the api-contract integration lane, which boots the generated router over real HTTP. It
40
+ also keeps this file runnable without ``--extra integration``.
41
+
42
+ The prompt-tier generators (payload / output-parser / output-prompt / render-helper /
43
+ extractor / trace-helper) are absent because they key off ``template.*`` nodes and this
44
+ corpus declares none — including them would emit nothing and read as coverage that is
45
+ not there.
46
+
47
+ The peer lanes are the same test in each port. If one port drops out, that port keeps
48
+ precisely the bug class this exists to catch — so a skip here is never "just this lane".
49
+ """
50
+ from __future__ import annotations
51
+
52
+ import importlib
53
+ import subprocess
54
+ import sys
55
+ from pathlib import Path
56
+
57
+ from metaobjects import load_uris
58
+ from metaobjects.codegen.config import GenConfig
59
+ from metaobjects.codegen.generators.entity_model import entity_model
60
+ from metaobjects.codegen.generators.filter_allowlist_generator import (
61
+ filter_allowlist_generator,
62
+ )
63
+ from metaobjects.codegen.generators.names_generator import names_generator
64
+ from metaobjects.codegen.runner import run_gen
65
+
66
+ # tests/codegen/ -> tests -> python -> server -> repo root
67
+ CORPUS = (
68
+ Path(__file__).parents[4]
69
+ / "fixtures"
70
+ / "persistence-conformance"
71
+ / "canonical"
72
+ / "meta.fitness.json"
73
+ )
74
+
75
+
76
+ def _load_corpus():
77
+ result = load_uris([CORPUS.as_uri()])
78
+ assert not result.errors, "The shared corpus must load cleanly before anything " \
79
+ "can be generated from it:\n" + "\n".join(
80
+ f" {getattr(e, 'code', 'ERROR')}: {e.message}" for e in result.errors
81
+ )
82
+ return result.root
83
+
84
+
85
+ def _generate(out_dir: Path) -> list[Path]:
86
+ """Run the model-tier generators through run_gen — the real orchestrator.
87
+
88
+ Going through ``run_gen`` rather than calling ``generate()`` on each generator is
89
+ deliberate: it is what composes each generator's own ``filter`` into ``ctx.matches``
90
+ (``runner._matcher``) and what emits the ``__init__.py`` files that make the output
91
+ an importable package. A harness that skipped it would measure itself.
92
+ """
93
+ config = GenConfig(out_dir=str(out_dir), emit_package_init=True)
94
+ result = run_gen(
95
+ config,
96
+ _load_corpus(),
97
+ generators=[entity_model(), names_generator(), filter_allowlist_generator()],
98
+ )
99
+ written = sorted(out_dir.rglob("*.py"))
100
+ assert written, f"the corpus generated no Python modules at all: {result.warnings}"
101
+ return written
102
+
103
+
104
+ def test_every_generated_module_imports(tmp_path: Path) -> None:
105
+ """Import each emitted module for real — the cross-module resolution check."""
106
+ out_dir = tmp_path / "generated"
107
+ written = _generate(out_dir)
108
+
109
+ sys.path.insert(0, str(tmp_path))
110
+ try:
111
+ failures: list[str] = []
112
+ for path in written:
113
+ dotted = ".".join(path.relative_to(tmp_path).with_suffix("").parts)
114
+ # A package's __init__ is imported under the package's own name.
115
+ if dotted.endswith(".__init__"):
116
+ dotted = dotted[: -len(".__init__")]
117
+ try:
118
+ importlib.import_module(dotted)
119
+ except Exception as exc: # noqa: BLE001 — every failure mode is a finding
120
+ failures.append(f"{path.relative_to(out_dir)}: {type(exc).__name__}: {exc}")
121
+ assert not failures, (
122
+ f"`metaobjects gen` over the shared fitness corpus emitted {len(written)} "
123
+ f"module(s), {len(failures)} of which do not import:\n" + "\n".join(failures)
124
+ )
125
+ finally:
126
+ sys.path.remove(str(tmp_path))
127
+ for name in [m for m in sys.modules if m.split(".")[0] == "generated"]:
128
+ del sys.modules[name]
129
+
130
+
131
+ def test_no_generated_module_references_an_undefined_name(tmp_path: Path) -> None:
132
+ """ruff F821 over the emitted tree — the branches importing never executes.
133
+
134
+ Scoped to the name-resolution rules on purpose. A generated file is allowed to be
135
+ untidy (an unused import is not an adopter's broken build); it is not allowed to
136
+ name something that does not exist.
137
+ """
138
+ out_dir = tmp_path / "generated"
139
+ _generate(out_dir)
140
+
141
+ proc = subprocess.run(
142
+ [
143
+ sys.executable, "-m", "ruff", "check",
144
+ "--no-cache",
145
+ "--isolated", # never inherit the repo's own ruff config
146
+ "--select", "F821,F822,F811,E9",
147
+ "--output-format", "concise",
148
+ str(out_dir),
149
+ ],
150
+ capture_output=True,
151
+ text=True,
152
+ )
153
+ assert proc.returncode == 0, (
154
+ "`metaobjects gen` over the shared fitness corpus emitted code that names "
155
+ "something undefined:\n" + proc.stdout + proc.stderr
156
+ )
File without changes
File without changes
File without changes