feat(schema)!: add inbound listeners to Assembly, remove per-endpoint port

What

Adds inbound listeners to the Assembly message. Introduces a Protocol enum and a Listener message, and adds repeated Listener listeners to Assembly: the externally-published inbound sockets (port + protocol) for the assembly's OCI image. Removes the per-endpoint port field from HTTPEndpoint/GRPCEndpoint.

Why

Part of DM-1b (work item #1). The DM-1a parity analysis identified the assembly's published port as a declarative fact missing from the schema.

The schema already let each endpoint declare its own port under Inbound, with no link to the single port a generated deployment manifest publishes, and Assembly already documents that its services "share a single process space and a single set of inbound ports", i.e. inbound ports are an assembly-level concern. A per-endpoint port contradicted that.

Correction: a Listener is the published socket (port + protocol) on the Assembly, and routes stay under each service's Inbound, see discussion.

Design notes

  • Assembly-level, not per-endpoint. One assembly is one OCI image, one process, sharing a single set of inbound ports. The services it composes contribute routes to that shared socket; the socket itself is an assembly property. The published listener maps to what a generated deployment manifest surfaces (a container port + its protocol).
  • repeated, capped at one for now. The validator rejects more than one listener today, matching what the deployment target publishes per built image. Modeling it as repeated keeps the "separate ports via configuration" topology from the SOA design reachable later as a non-breaking validator change rather than a schema edit.
  • Empty list = subscriber-style assembly. An assembly with no listeners publishes no inbound port (e.g. one whose services only subscribe to NATS subjects, process, and publish). NATS endpoints are subscriptions, not listeners, so they carry no port; len(listeners) == 0 cleanly identifies a consumer-style assembly.
  • Protocol is a required enum. PROTOCOL_HTTP / PROTOCOL_GRPC, required whenever a listener is set.
  • Breaking change. Removes HTTPEndpoint.port / GRPCEndpoint.port (field 1, now reserved). The schema has no consumers yet, so this is the best time to move the listen port to where it belongs rather than carry the inconsistency.

Follow-up (not in this MR)

To fully match the SOA design's content-type multiplexing (gRPC + HTTP on one port), Listener.protocol would become a list. That can't be done by re-typing the field later (it's a breaking wire + codegen change), so it would land as either a new field on Listener OR treating Protocol as optional, if a concrete multiplexing consumer appears. Tracked in the discussion.

Edited by Lucas Charles

Merge request reports

Loading
Loading