1.0.3
All four registries publish: npm 1.0.3 (full lockstep across all 14 @metaobjectsdev/*
publish candidates), Maven Central 8.0.3, PyPI 1.0.3, NuGet 1.0.3. PyPI and NuGet were
last cut at 1.0.1 and adopt the shared minor.patch now current, skipping the number they
sat out (ADR-0035 Amendment 1).
Coordinated PATCH. Every port has changed product code: npm carries FR-023 and the
ADR-0055 reference implementation, Maven / NuGet / PyPI each carry their ADR-0055 port, and
PyPI additionally carries FR-023 Phase 1a. metamodelVersion stays 1.0 —
expected-registry.json is byte-unchanged since v1.0.2, so no registered vocabulary,
canonical format or wire contract moved.
Added
- Metadata dependencies (FR-023, Phase 1a — TypeScript + Python). A project can
now build on a metadata model published by another repository or package instead
of copy-pasting it:dependenciesin.metaobjects/config.json—[{ name, path }]today (the
npm/pythontransport keys are reserved in the schema and refused bysync
withERR_DEPENDENCY_UNRESOLVED, "not supported by this toolchain yet").meta deps sync [<name>…] [--dry-run]/meta deps check/meta deps list—syncresolves each dependency'spath, validates its manifest and
artifact hash, re-loads the artifact standalone with core providers, and writes
the committed snapshot (.metaobjects/deps/<name>/) + lock
(.metaobjects/deps.lock.json);checkcompares the currently-installed
artifact's hash against the lock, read-only;listprints the lock.verify --deps— the same drift comparison asmeta deps check, as a
gatedverifysubverb (needs the publisher'spathreachable, so it is never
part of the bare-verifydefault).driftedorunresolvedfails with the new
ERR_DEPENDENCY_UPSTREAM_DRIFT.sharedModelFile()(@metaobjectsdev/codegen-ts) — the publisher-side
generator: selects a subset of a project's own metadata by thescope
pattern grammar, closure-checks it, and emits one canonical-JSON artifact +
metaobjects.pkg.jsonmanifest. Registered and discoverable (meta gen --list), but deliberately not offered bymeta eject --list— the
artifact is a contract whose bytes a cross-port corpus pins and whose hash
consumers verify, so a user-owned editable copy would invite a silent break.- An overlay authoring lint in
meta verify— advisory, runs on every
invocation (no subverb): a top-level(type, resolutionKey)declared in two or
more collection files (dependency artifacts included) where more than one
declaration lacksoverlay: true. Never fails the build; mute with
--no-overlay-lint/META_NO_OVERLAY_LINT=1. ERR_DEPENDENCY_PACKAGE_NOT_OWNED— a project mayextendsoroverlay: truea dependency's node freely, but declaring a brand-new top-level node
into a package a dependency owns is refused by name, naming the fix.- New error codes altogether:
ERR_DEPENDENCY_UNRESOLVED,
ERR_DEPENDENCY_MANIFEST_INVALID,ERR_DEPENDENCY_SNAPSHOT_STALE,
ERR_DEPENDENCY_NODE_COLLISION,ERR_DEPENDENCY_METAMODEL_INCOMPATIBLE,
ERR_DEPENDENCY_UPSTREAM_DRIFT,ERR_DEPENDENCY_PACKAGE_NOT_OWNED. - New exports:
declaredTopLevelKeys(@metaobjectsdev/metadata— the raw,
pre-parse walk the overlay lint and the loader's own overlay-only partition
share) andserializeSharedDocument(the canonical shared-artifact
serializersharedModelFile()targets; Python'sserialize_shared_document
is byte-identical, though Python has no publisher CLI wired to it yet —
sharedModelFile()itself is TypeScript-only in Phase 1a).FileSource's
constructor takes an optional{ id }, so a dependency's synced snapshot
loads withdep:<name>/<artifact>provenance instead of reading like a
local file. - Deliberately not built in Phase 1a — see
docs/features/metadata-dependencies.md
("Deferred"): thenpm/python/maven/nugettransports, a local
co-development override, a usage-aware breaking-change classifier, cross-boundary
codegen imports (packageBindings), a runtimeObjectManagerscope predicate,
and Java/Kotlin/C# as dependency consumers or publishers (Phase 2). - No registered vocabulary changed —
metamodelVersionstays1.0.
Docs:docs/features/metadata-dependencies.md. Corpus:
fixtures/dependency-conformance/(23 cases, TS + Python).
Changed
- A project that declares
scope.includenow sees its requirements-ledger
denominator narrow to that scope — even with zero dependencies. The ledger's
"coverable" object count is computed by
Collection.inScope, which ismatchesScope(fqn, scope) && …regardless of
whether the project has anydependenciesat all. Previously the ledger counted
every non-abstract entity in the loaded model; a project that scopes its own
codegen withscope.includenow has its ledger coverage counted only over that
declared scope too. This is a real behavior change for an existing project that
already declaresscope.includeand reads itsmeta verifycoverage numbers —
they may drop even though nothing was deleted. meta verifynow runs the overlay authoring lint for EVERY project, not just
one withdependenciesdeclared.runOverlayLintAdvisory()is unconditional —
it lintscollection.files, which for a zero-dependency project is simply its
own files — so a project with no dependencies at all, but with a top-level
(type, resolutionKey)redeclared across two or more of its own files (e.g. the
"Optional layered overlay pattern" — ameta.user.json+
meta.user.ui.json+meta.user.db.jsonsplit), now gets new advisory
WARN_OVERLAY_IMPLICIToutput onmeta verifyit did not get before this
release. Advisory only — never fails the build, mute with--no-overlay-lint/
META_NO_OVERLAY_LINT=1— but this is a second, real carve-out from "a project
with no dependencies behaves identically," alongside the ledger-denominator one
above.Collection(@metaobjectsdev/sdk) gainsdependencies,ownFiles,
fileIds,importedPackages,importedNodes,imported(fqn),
declaredMigrateScope;inScopeandinMigrateScopeare now the COMPOSED
predicates described above (default-exclusion of imported metadata) — byte-for-byte
identical to their prior behavior for a project with nodependenciesand no
declaredscope/migrate.scope.- The scope-pattern grammar (
compileScope/matchesScope/compilePattern)
moved from@metaobjectsdev/sdkto@metaobjectsdev/metadata— pure,
browser-safe string code, so@metaobjectsdev/codegen-ts(thesharedModelFile()
publisher side) can use it without asdkdependency.sdkre-exports it
unchanged; existing importers ofcompileScope/matchesScopefromsdkare
unaffected. scopeExpectedSchema(@metaobjectsdev/migrate-ts) takes a third, optional
{ imported }argument: an imported object the scope does not admit is removed
from the expected schema beforedeclaredSchemasis computed — so importing a
table-backed entity can never turn the publisher's other tables intoDROP
candidates, and never proposes creating the imported table.scanRequirements(@metaobjectsdev/cli) takes an optional second argument,
{ coverable }— the predicate the ledger denominator change above threads
through.
Deprecated
@metaobjectsdev/sdk: the v0.3package.meta.jsonprototype and workspace discovery —
PackageManifestSchema,PackageManifest,PACKAGE_MANIFEST_FILE,readPackageManifest,
resolveMetaobjectsPackage,discoverWorkspace,resolveExtendsOrder,packageLabel,
Workspace,WorkspacePackage. Nothing in the toolchain reads apackage.meta.json;
cross-repo metadata sharing is being built as FR-023 (metadata dependencies). They still work
and are removed in 2.0.
Fixed
-
overlay: trueno longer depends on file order — the loader applies overlays in a
deferred pass (ADR-0055). The
parser used to resolve an overlay against the accumulating tree the instant it met it, so the
declaration it re-opens had to have been parsed already.extendshas never had that
constraint: it is deferred to a pass that runs after every source is read. Overlays now work
the same way — every source is parsed first, applying only plain declarations, and the queued
overlays are applied afterwards, before super-resolution.What this fixes, concretely:
- A MIXED file — one carrying both plain and
overlay: truetop-level declarations —
failedERR_OVERLAY_NO_TARGETwhenever its target lived in a later-sorted file. The #160
partition that was meant to prevent this tested whole FILES (is every declaration in this
file an overlay?), so a mixed file was classified as a base and never moved. That partition
is now deleted in every port; nothing needs it. - An overlay declared above its base in the same file now loads, in JSON and in YAML.
- Python diverged silently rather than failing. Its loader merges post-parse, so its
partition chose which node absorbed which: with an overlay-first root as the accumulator
the base was merged INTO the overlay, producing children[ov, id]where every other port
produces[id, ov]— a difference the byte-gated canonical contract cares about. Folding
every root through one matcher also fixes two declarations of one name in a SINGLE Python
file staying two disconnected siblings. - Java reported
ERR_UNKNOWN. Its throw carried no structured code, so the code was
scraped from the message and found nothing. It now emitsERR_OVERLAY_NO_TARGETwith the
same message wording as every other port. - One bad overlay no longer discards its whole source. The eager throw abandoned the
entire document, losing every sibling declaration and cascading intoERR_UNRESOLVED_SUPER;
each overlay is now applied independently and every failure is reported.
Two behaviour changes ride along, both pinned by the corpus.
ERR_OVERLAY_NO_TARGET's
envelope moves from the parse-timeformat: "json"/"yaml"shape to ADR-0009 FR5d's
format: "resolved", carrying the samefiles/jsonPathplusreferrerandtarget. And
because the queue is unconditional — an overlay is deferred even when its target is already
present, since applying it eagerly "when the base happens to be there" is the retry-on-miss
variant ADR-0055 rejects — an overlay now lands after every plain declaration, including an
unflagged redeclaration in a later file that previously landed after it. Reaching that
corner requires an unflagged second declaration of a node, whichmeta verifyalready reports
asWARN_OVERLAY_IMPLICIT.metamodelVersiondoes not move (it stays1.0): no registered vocabulary, canonical
format or wire contract changed. This is additive on the metadata axis — input that failed now
loads, and nothing that loaded stops loading. Shipped in all five ports (TypeScript, C#, Java,
Kotlin via the JVM loader, Python), gated by nine new conformance fixtures. - A MIXED file — one carrying both plain and