You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The metadata loaders already accept consumer providers in every language — a runtime/library app that loads the metamodel can plug in its own provider and it merges on top of core. The gap is purely at the CLI / build-tool layer: on non-TS ports there is no idiomatic way to hand the app's provider to the loader the CLI already uses.
Verified: the library path works as designed
TS: loadMemory({ providers }) / new MetaDataLoader({ registry }).
So an application loading the metamodel at runtime can extend it, in both languages, today. This is not the problem.
The gap: the CLI can't supply the provider (non-TS)
TS CLI: reads metaobjects.config.tsproviders and threads them into loadMemory. ✅
Python CLI: _cmd_gen / _verify_codegen → _load_root → MetaDataLoader.from_directory(dir) — the convenience classmethod that uses core providers only, with no config to name a consumer provider. So the bare metaobjects gen / verifycannot load an app's custom subtype, even though the underlying MetaDataLoader would accept it. ❌ This is the concrete missing piece.
Java / C#: codegen runs as a build plugin (Maven/Gradle / MSBuild) with the project classpath, so it can see a compiled consumer provider — but that provider path is undocumented (own-your-codegen covers custom generators, not custom providers/subtypes).
Why it must load the provider CLASS, not a JSON file
A provider carries code, not just declarations:
factory is always code (FactoryMap = (typeId, name) => MetaData) — even the data-driven defineProviderFromData path takes a code factory map.
TypeDefinition.validate?: NodeValidator — an optional imperative validator (custom enforcement logic).
JSON can express the declarative surface (types / attrs / childRules / descriptions) but not the factory or a validator. So the mechanism has to load the app's native provider class in each language.
No single uniform mechanism — idiomatic per port (A4)
This is not a parity bug; it is inherent:
Interpreted (TS / Python): standalone CLI + a config that names/imports the provider module.
Compiled (Java / C#): build-plugin + classpath/assembly (cannot import a source module at CLI runtime).
Consistent with the ratified A4 ("own your codegen is idiomatic per-port").
Proposed for 1.0
Python CLI provider hook — the concrete missing piece: a metaobjects.config.py / entry-point / --provider module:symbol that _load_root imports and passes as MetaDataLoader(providers=[*core_providers, <that>]). Parity with TS config.providers.
Document the JVM / C# provider-via-classpath path in own-your-codegen.md (custom providers / subtypes, not just generators).
Optional convenience — for behaviorless subtypes (attr-only, factory = a shared default like new MetaView), support a pure-declarative provider JSON so the common case needs zero per-language code. A deep adopter's view.* subtype is exactly this case — it forced a "strip the custom nodes" workaround to run the non-TS model-gen CLI.
1.0 readiness
Add an F3/D4 line: non-TS CLIs need their idiomatic consumer-provider load hook; the loaders already accept providers — only the CLI convenience path (from_directory) is core-only.
(Supersedes the earlier 'just make it a JSON file' framing: the loaders already work; this is a per-port CLI/build-tool load hook, and it must load a native provider class because providers carry factory + optional validator code.)
Summary
The metadata loaders already accept consumer providers in every language — a runtime/library app that loads the metamodel can plug in its own provider and it merges on top of core. The gap is purely at the CLI / build-tool layer: on non-TS ports there is no idiomatic way to hand the app's provider to the loader the CLI already uses.
Verified: the library path works as designed
loadMemory({ providers })/new MetaDataLoader({ registry }).MetaDataLoader(providers=[*core_providers, my_provider])—loader/meta_data_loader.py__init__(providers=...)→compose_registry(...).So an application loading the metamodel at runtime can extend it, in both languages, today. This is not the problem.
The gap: the CLI can't supply the provider (non-TS)
metaobjects.config.tsprovidersand threads them intoloadMemory. ✅_cmd_gen/_verify_codegen→_load_root→MetaDataLoader.from_directory(dir)— the convenience classmethod that uses core providers only, with no config to name a consumer provider. So the baremetaobjects gen/verifycannot load an app's custom subtype, even though the underlyingMetaDataLoaderwould accept it. ❌ This is the concrete missing piece.own-your-codegencovers custom generators, not custom providers/subtypes).Why it must load the provider CLASS, not a JSON file
A provider carries code, not just declarations:
factoryis always code (FactoryMap = (typeId, name) => MetaData) — even the data-drivendefineProviderFromDatapath takes a code factory map.TypeDefinition.validate?: NodeValidator— an optional imperative validator (custom enforcement logic).JSON can express the declarative surface (types / attrs / childRules / descriptions) but not the factory or a validator. So the mechanism has to load the app's native provider class in each language.
No single uniform mechanism — idiomatic per port (A4)
This is not a parity bug; it is inherent:
Consistent with the ratified A4 ("own your codegen is idiomatic per-port").
Proposed for 1.0
metaobjects.config.py/ entry-point /--provider module:symbolthat_load_rootimports and passes asMetaDataLoader(providers=[*core_providers, <that>]). Parity with TSconfig.providers.own-your-codegen.md(custom providers / subtypes, not just generators).loadMemorydoesn't threadconfig.providers).new MetaView), support a pure-declarative provider JSON so the common case needs zero per-language code. A deep adopter'sview.*subtype is exactly this case — it forced a "strip the custom nodes" workaround to run the non-TS model-gen CLI.1.0 readiness
Add an F3/D4 line: non-TS CLIs need their idiomatic consumer-provider load hook; the loaders already accept providers — only the CLI convenience path (
from_directory) is core-only.(Supersedes the earlier 'just make it a JSON file' framing: the loaders already work; this is a per-port CLI/build-tool load hook, and it must load a native provider class because providers carry factory + optional validator code.)