Architecture and data flow¶
cwl2oci is a transformation plugin, not a command-line application. It depends
on the framework-neutral contracts in transpiler-mate-api; a host runtime owns
source resolution, metadata preparation, option transport, and plugin discovery.
host runtime
resolves CWL and selects #process-id
normalizes SoftwareApplication metadata
validates CWL2OCIOptions
|
v
cwl2oci plugin registration
maps metadata and the selected process
validates the annotation model
serializes {"$manifest": {...}}
|
v
annotations.json
Why a process must be selected¶
A CWL document can contain multiple processes. Values such as the entry point,
CWL version, and process class must describe one target, so the plugin rejects a
context whose resolved_process is None. Selecting a #<process-id> is a
runtime responsibility.
Two annotation namespaces¶
The plugin combines two kinds of metadata:
org.opencontainers.image.*describes the packaged software using keys standardized by the OCI Image Specification.org.cwl.*records CWL-specific execution identity and has no claim on OCI's reserved namespace.
OCI permits namespaced extension annotations and requires consumers to tolerate unknown keys. This lets CWL-specific metadata travel in the same string map as standard image metadata.
The $manifest envelope¶
OCI defines an annotations map inside manifests and descriptors, but it does
not define the $manifest wrapper written here. $manifest comes from the ORAS
annotation-file format and directs ORAS to apply the map to a manifest. cwl2oci
only generates the JSON file; it does not build an image or modify an OCI
manifest itself.
Model boundary¶
schemas/oci_annotations.yaml defines the generated OciAnnotations Pydantic
model. The plugin constructs this model before serialization, which enforces the
required annotation values and aliases Python field names to dotted annotation
keys. Optional provenance and CWL-version fields disappear when unset.