Skip to content

v0.22.0 — capability requirements are metadata (coordinated MINOR)

Choose a tag to compare

@dmealing dmealing released this 13 Aug 09:45
· 1074 commits to main since this release

Coordinated MINOR — npm 0.22.0 · PyPI 0.22.0 · NuGet 0.22.0 · Maven Central 7.22.0.

Cut as MINOR, not PATCH, because pre-1.0 ^0.21.x resolves <0.22.0: the registry tightening below is potentially breaking for a downstream provider, and a consumer should adopt it deliberately rather than on a routine npm update. Nothing here changes runtime behaviour on an existing database.

Capability requirements are metadata — requirement.functional / requirement.architectural

Registered metamodel vocabulary in all five ports, declared in metaobjects/ beside the entities they describe and loaded by the same loader. No side file, no bespoke parser.

  • Two kinds, opposite checks. functional fails when NOTHING implements it (existence); architectural fails when something VIOLATES it (universality) — and carries no level, because a policy is object-independent by definition.
  • Hierarchy is nesting, not a parent string: regrouping moves a subtree, and a requirement is addressable by the same dotted child-name path as every other node.
  • Five levels, link floor at L4. @implementedBy is legal at L4/L5 only (ERR_REQUIREMENT_LINK_ABOVE_FLOOR).
  • @status is a closed enum the LOADER enforces (live | partial | abandoned | superseded), so a typo fails the load in every language rather than passing silently in four of them.
  • A dangling @implementedBy is an ERROR on live/partial and CORRECT on abandoned/superseded — that asymmetry is the mechanism's whole point. Do not "fix" the abandoned case by deleting the entry; that destroys the record it exists to preserve.
  • @verifiedBy checks each named test exists and is not skipped — it never runs them, and fails OPEN when no test files are visible.
  • Object coverage ships as a WARNING, deliberately: on a real 120-file repository carrying one requirement it reports 93 unclaimed entities.

Entirely opt-in: a model with no requirement.* nodes produces no diagnostics, and no codegen, migrate or runtime path reads the type. Adopter guide: docs/features/requirements.md.

Fixed — template.* owns its attributes (all five ports, ADR-0050)

FR-033 had re-homed template.*'s attributes — including the required @payloadRef / @toolName — into the composable metaobjects-prompt provider. Composing without it left template.prompt registered with ZERO attributes, so ERR_MISSING_REQUIRED_ATTR simply stopped firing and invalid metadata began loading clean. ADR-0050: OWN attributes travel with their type; PROJECTED attributes must be optional.

Added — ERR_EXTEND_REQUIRED_ATTR (registry tightening)

Potentially breaking for a downstream provider. Projecting a REQUIRED attribute onto a type another provider owns now throws, in every registry, across both doors (extend and registerCommonAttrs). No provider in this repository does it (a sweep of all 54 spec files found zero), so the change is preventative.

Fixed — undeclared attributes rejected on requirement.* and 12 more Java types (ADR-0051)

ADR-0051: ADR-0011 and ADR-0023 were never in conflict — extension is registration. A wildcard is worse than a permissive extension point, because it also swallows a typo'd core attribute, silently, on one port only.

Known and NOT fixed: template.* still accepts undeclared attributes on Java — the one wildcard deliberately retained. Removing it trips ERR_BAD_ATTR_VALUE on abstract: true, because Java models isAbstract as an ATTRIBUTE while TypeScript models it as a NATIVE FIELD. Closing it needs isAbstract homed consistently across the ports first — a metamodel decision.

Two defects caught by this release's own external smoke test

Both with 9/9 CI lanes green, and both fixed before publish:

  • An assigned primary key generated code that did not compile. An entity whose PK carries no identity.primary @generation emitted an InsertSchema marking it .optional(), while its Drizzle column text("id").primaryKey() has no default and is insert-required → TS2769. Now gated by a test that compiles the entity and queries files together, since the defect lived between them.
  • @metaobjectsdev/cli shipped a yaml dependency it never imports, orphaned when requirements became registered vocabulary.

See CHANGELOG.md for full detail.