Skip to content

Give the Resolved Deployment a metamodel and validate the worked projection #42

Description

@ExtraToast

Parent

#35

What to build

The Resolved Deployment and its per-Application projection get a metamodel: the assignments per Process, the path plan (0070), the release gate's inputs (0071), provenance, and a place for the trace. Chapter 20's worked projection is validated against it in CI, which forces the fixes it needs today:

  • no health timeout class (chapter 20 deleted the concept); the release gate appears instead;
  • provenance lists one digest per pinned input (every Intent Fragment, the Platform document, the node contract, the images lock, the ClusterState snapshot) and the schema package integrity, with no contextRef and no adapterCompat;
  • the ingest worker's declared placement matches chapter 10's numbers and does not author a disk size, which is derived;
  • the authority table's duplicated volumes[].durability row goes.

Settled in this ticket: layer 2 records decisions in model words. Cutover, eligible nodes, the hardening posture, the tier and the middleware chain are model concepts; RollingUpdate, securityContext fields, node-selector label keys and object kinds are spelled by the kubernetes adapter, exactly as Traefik's spellings already belong to the traefik adapter. This is recorded as an amendment to 0097. The review surface can still show the rendered spelling, through the trace.

0029's "Settled by" names the new schema, so its settling test runs in this repository instead of against deploy-config-schema.

Parity

The Resolved Deployment metamodel is the target metamodel for Task 2 (QVT-Operational, due 2026-10-16), so it is also due for Task 1 (2026-09-25) in both implementations. This ticket:

  • adds the Resolved Deployment's classes to spec/v1/examples/expected/descriptor.json struck 2026-09-16, see the amendment below;
  • commits chapter 20's worked projection as spec/v1/examples/knowledge/expected/resolved.json in canonical JSON, validated against the metamodel. It is the first resolved.json oracle; the resolver tickets add one per example.

Layer 2 recording decisions in model words is what makes the oracle implementation-neutral: no Kubernetes, Traefik, Zod or Ecore spelling may appear in resolved.json. (Amended 2026-09-14 for the revised proposal, #102.) The model-driven target metamodel (#87) holds this layer together with the typed resources, so it neither joins the descriptor nor loads resolved.json; resolved.json binds this implementation only. This ticket also exports the worked projection's resolved dependency edges as spec/v1/examples/knowledge/expected/dependencies.json, which both implementations match.

(Amended 2026-09-14.) This ticket also commits minimal's resolved.json, moved here from #82: the first Resolved Deployment oracles are written against the metamodel this ticket gives them.

Acceptance criteria

  • The worked projection validates against the metamodel in CI.
  • Reintroducing any of the four defects above fails validation.
  • No Kubernetes or Traefik field name is a key in the Resolved Deployment metamodel.
  • 0097 carries the amendment, 0029's settling command runs here, and both pass lint:adrs.
  • The worked projection is committed as canonical resolved.json and validates against the metamodel.
  • minimal carries a canonical resolved.json, written and reviewed by hand, which validates against the metamodel.
  • The descriptor carries the Resolved Deployment metamodel, and struck 2026-09-16, see the amendment below. The rest of the criterion stands and is met: no key in the metamodel or in resolved.json names a Kubernetes, Traefik, Zod or Ecore concept.

Blocked by


Amended 2026-09-16

The descriptor does not carry the Resolved Deployment metamodel, and should
not.
The parity contract
is normative for code and says the descriptor lists every class of the
source metamodel, with target structures compared through what they
generate rather than structurally. Where this ticket and that document
disagreed, the document won, which is the same precedence the repository uses
between a chapter and an ADR.

Two lines above are struck for that reason. What was built instead:

  • The Resolved Deployment has its own wire schema, and chapter 20's worked
    projection is parsed out of the Markdown and validated against it (REQ-033).
  • minimal and knowledge carry committed resolved.json oracles, which bind
    the production implementation only, and knowledge carries dependencies.json,
    which binds both (REQ-035).
  • A test walks every property name both documents declare, and the committed
    oracles too, and fails on any Kubernetes or Traefik field name. That is the
    half of the struck criterion that always made sense, and it is enforced rather
    than asserted.
  • On the model-driven side, Model the Resolved Deployment target metamodel in Ecore #87 added a test proving no class of the target
    package reaches the descriptor, allowing exactly three names through:
    Cutover, Match and DurabilityClass are the source metamodel's own
    vocabularies, carried over because they mean the same thing.

Landed in #135 and #136.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.component: configConfiguration schema, defaults, or repo settings.priority: P2Medium; normal planned work.type: featureNew user-facing or operator-facing capability.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions