- docs
- Reference
- Reference
- Metadata
- Metadata: Dependencies
Metadata: Dependencies
The dependencies array of metadata.json declares the packages a package needs at runtime.
Dependencies
Section titled “Dependencies”Every dependency identifier is pinned by OCI digest in the published form. The same dependency graph is therefore reproduced on every machine regardless of the current registry state.
- Limit: a package declares at most 256 dependencies, and a longer array is rejected when the file is read (
too many dependencies, exit 65) - The platform a bundle targets is not part of this file. On the wire it lives in the OCI Image Index. Between
ocx package createandocx package pushorocx package testit lives in a build receipt, readable withocx package receipt. - Authoring sidecar versus published form: the digest is optional while authoring and mandatory once published. The published form is a strict subset of the authoring form, so an already-published
metadata.jsonis a valid sidecar forocx package createandocx package pushand needs no migration.
See Dependencies in depth for the pin rules and Declaring dependencies for the publisher workflow.
Dependency Entry
Section titled “Dependency Entry”| Field | Type | Required | Description |
|---|---|---|---|
identifier | string | Yes | OCX identifier with an explicit registry; one without is rejected at deserialization. In the authoring sidecar the digest is optional, and a tag-only identifier tells ocx package create to resolve it. In the published form the digest is mandatory and must reference a platform manifest, never an OCI Image Index. The tag is always advisory. E.g. ocx.sh/java:21@sha256:a1b2c3d4e5f6.... |
name | string | No | Short name used to reference this dependency in ${deps.NAME.installPath} templates, instead of the repository basename. Must match ^[a-z0-9][a-z0-9_-]*$ and be at most 64 characters. |
visibility | string | No | Controls how the dependency’s environment variables propagate. Default: sealed. See Visibility. |
{ "$schema": "https://ocx.sh/schemas/metadata/v1.json", "type": "bundle", "version": 1, "env": [ { "key": "PATH", "type": "path", "required": true, "value": "${installPath}/bin", "visibility": "public" }, { "key": "JDK_HOME", "type": "constant", "value": "${deps.java.installPath}", "visibility": "public" } ], "dependencies": [ { "identifier": "ocx.sh/java:21@sha256:a1b2c3d4e5f6...", "visibility": "private" }, { "identifier": "ocx.sh/kitware/cmake:3.28@sha256:f6e5d4c3b2a1...", "name": "cmake" } ]}Visibility
Section titled “Visibility”A dependency’s visibility controls how its environment variables propagate through the dependency chain. It has two boolean axes: private (visible to the package’s own runtime) and interface (propagated to consumers).
| Value | Private surface (--self) | Interface surface (default) | Use case |
|---|---|---|---|
sealed (default) | No | No | Structural dependency: content accessed by path, not env. Most deps. |
private | Yes | No | Package’s own shims need the dep’s env; consumers don’t. |
public | Yes | Yes | Both the package and consumers need the dep’s env. |
interface | No | Yes | Meta-packages that forward env to consumers without using it. |
has_private()istrueforprivateandpublic.has_interface()istrueforpublicandinterface.- The composer uses these accessors to gate entry emission per surface at exec time.
Transitive Propagation
Section titled “Transitive Propagation”Along a chain (Root, Dep, Transitive), Visibility::through_edge(child_eff) yields sealed when the child’s effective visibility does not export to consumers (child_eff.has_interface() == false), and the edge unchanged otherwise.
| Edge | Child effective | Result (from root) |
|---|---|---|
public | public / interface | public |
public | private / sealed | sealed |
private | public / interface | private |
private | private / sealed | sealed |
interface | public / interface | interface |
interface | private / sealed | sealed |
sealed | any | sealed |
Diamond Merge
Section titled “Diamond Merge”When two paths reach the same dependency, the most open visibility wins: each axis is OR-merged independently via Visibility::merge. It is computed at install time and stored in resolve.json (see Env Composition: Edge Filter).
Ordering
Section titled “Ordering”Array position defines the canonical order for environment composition, and the first entry’s environment is applied first. The dependency graph is walked depth first with dependencies before dependents, and a package reached twice keeps its first position.