Documentation
¶
Overview ¶
Package loader is the kernel's one artifact-loading routine: it builds a single CUE package — from a directory or from an in-memory overlay — and runs the OPM artifact shape gate over the result, and it fetches a published artifact of any OPM kind from an OCI registry through CUE's native module machinery (FetchArtifact, with FetchModule the #Module entry over it; ADR-009).
The gate is the acquisition boundary's fast-fail structural check: it confirms an artifact carries the right concrete kind and the identity fields the schema never defaults, but deliberately stops short of full schema validation, which is the kernel's contract. "Concrete" is judged before default finalization: an identity field authored as a defaulted disjunction is refused, with the default named in the error. Single-sourcing the build and the gate here guarantees a directory-loaded artifact and a registry-loaded artifact are evaluated, gated and error-wrapped identically; the only difference between the entry points is where the package files come from.
It lives under opm/internal/ so it stays off the library's public SemVer surface (Principle VI, VII) while remaining importable by opm/kernel and the kernel's other internals. The sentinels it wraps are declared in opm/errors, the package a frontend can reach for errors.Is.
The package does not import opm/internal/synth: synthesis builds THROUGH LoadDir, never the other way round.
Index ¶
- Variables
- func FetchArtifact(ctx context.Context, cueCtx *cue.Context, modPath, version string, ...) (cue.Value, *opmmodule.Source, error)
- func FetchModule(ctx context.Context, cueCtx *cue.Context, modPath, version string, ...) (cue.Value, *opmmodule.Source, error)
- func LoadDir(ctx *cue.Context, root, pkg string, overlay map[string][]byte, env []string, ...) (cue.Value, error)
- type ArtifactSpec
- type ModuleRef
Constants ¶
This section is empty.
Variables ¶
var ( ModuleSpec = ArtifactSpec{ Label: "module", ExpectedKind: "Module", RequiredConcreteFields: []string{"metadata.name", "metadata.modulePath", "metadata.version"}, } InstanceSpec = ArtifactSpec{ Label: "instance", ExpectedKind: "ModuleInstance", RequiredConcreteFields: []string{"metadata.name", "metadata.namespace"}, ModuleRefs: []ModuleRef{{Path: "#module"}}, } // #Platform.#registry carries path-keyed #CatalogEntry values, each // embedding its catalog by import (enhancement 0019 D5). Core derives the // entry's `version` from the embedded catalog's stamped metadata, so an // entry that names no catalog (the retired subscription shape: a // `version` scalar and nothing else) is refused here as a missing // required field naming the entry. #registry is a definition, so no // root-level validation reaches it; the gate walks it explicitly. PlatformSpec = ArtifactSpec{ Label: "platform", ExpectedKind: "Platform", RequiredConcreteFields: []string{"metadata.name", "type"}, CompleteEntryMaps: []string{"#registry"}, } // A #Catalog carries no metadata.name: its identity is the module path // it is published under plus the version stamped on every member it // ships (core src/catalog.cue). Those are the two fields core declares // required with no default, so they are the two this gate requires; // metadata.fqn is derived from modulePath and adds nothing to check. // The member maps (#resources, #traits, #blueprints, #transformers) are // pattern constraints whose values are member schemas, non-concrete by // construction, so nothing here walks them — the catalog's derivations // read them on demand (ADR-009). CatalogSpec = ArtifactSpec{ Label: "catalog", ExpectedKind: "Catalog", RequiredConcreteFields: []string{"metadata.modulePath", "metadata.version"}, } )
ModuleSpec, InstanceSpec, PlatformSpec and CatalogSpec are the shape-gate definitions for the four artifacts the kernel acquires. The required field lists carry only the identity fields the schema never defaults — fields the schema fills in (or leaves as open `_`) are out of scope here and validated by the kernel.
Functions ¶
func FetchArtifact ¶
func FetchArtifact(ctx context.Context, cueCtx *cue.Context, modPath, version string, env []string, spec ArtifactSpec) (cue.Value, *opmmodule.Source, error)
FetchArtifact loads an OPM artifact published in an OCI registry, identified by its major-qualified module path (e.g. "example.com/modules/hello@v0") and version (e.g. "v0.0.2"), gated to the shape spec names, and returns the value built in cueCtx together with the staged source tree the build used, as the artifact opmmodule.Source in overlay mode: the deterministic synthetic Root every overlay key sits under, plus the Overlay carrying the module's .cue files (its own cue.mod/module.cue included, nothing else: the set cue/load reads). A consumer reuses it to build a follow-on package INSIDE the module's own main module — letting the module's already-tidied cue.mod/module.cue drive transitive resolution — without a second registry fetch (Principle V, CUE-native resolution). The returned Overlay is the build's own map; callers that mutate it (e.g. to overlay additional files) MUST clone it first.
It fetches the module's source via CUE's native module machinery (mod/modconfig) and builds it IN MEMORY AS THE MAIN MODULE through LoadDir's overlay mode: the fetched files are the overlay under a deterministic synthetic root, so the module's own cue.mod/module.cue drives transitive dependency resolution and its kind/metadata are evaluated at the package root. No wrapper package is synthesized and no temporary directory is written.
Because the build IS LoadDir — the kernel's one evaluate-and-shape-gate routine, the same call directory acquisition makes — the fetched artifact is evaluated, shape-gated against spec (its concrete kind and its concrete identity fields) and error-wrapped exactly as a directory artifact of that kind is, wrapping the shared ErrInvalidPackage / ErrWrongKind / ErrMissingRequiredField sentinels. The two acquisition paths differ only in where the package files come from. Neither performs full schema validation, which remains the kernel's contract.
Everything up to and including the staging reads no kind: fetching and unpacking a published CUE module artifact is the same work whatever OPM kind its root package declares, which is why one routine serves every kind and the kernel holds no second fetch path (ADR-009). spec is the only thing that differs between them.
env is the environment slice the fetch resolver and the load both consult — the kernel's CUE_REGISTRY mapping via [cueenv.Override], nil to read the process environment unchanged. The process environment is never mutated. Parse failures on caller input are wrapped rather than panicked.
func FetchModule ¶
func FetchModule(ctx context.Context, cueCtx *cue.Context, modPath, version string, env []string) (cue.Value, *opmmodule.Source, error)
FetchModule loads a #Module published in an OCI registry: FetchArtifact with ModuleSpec, plus the coordinate identity check that is the module path's alone ([verifyModuleIdentity], 0010 D11). It is the registry path's single entry for modules, so the check runs for every caller behind it.
Other kinds go through FetchArtifact with their own spec and do NOT get the coordinate check: the requirement admitting the catalog kind (ADR-009) names only the shape refusal, and a kernel that refuses on something no requirement describes is worse than an unchecked coordinate. Generalizing the check is its own change.
func LoadDir ¶
func LoadDir(ctx *cue.Context, root, pkg string, overlay map[string][]byte, env []string, spec ArtifactSpec) (cue.Value, error)
LoadDir is the kernel's one evaluate-and-shape-gate step. It builds exactly one CUE package — pkg, relative to the module root at root — in ctx and runs the artifact shape gate described by spec over the result. The two source modes are selected by overlay:
- overlay == nil → on-disk package: load.Config.Dir is root and the files are read from the filesystem. root must exist and be a directory.
- overlay != nil → in-memory package: the overlay supplies the .cue files under root (its cue.mod/module.cue included; the set cue/load reads) and root doubles as the module root, so the staged cue.mod/module.cue drives transitive dependency resolution. This is how a registry-fetched module (FetchArtifact stages the fetch under a synthetic root and builds it here, for every kind), a values-layered instance package and a synthesized instance package are all built.
pkg is a package path relative to root ("." or "" for the root package, "./sub" for a subdirectory). env, when non-nil, is the environment slice load.Config consults — the CUE_REGISTRY override the kernel plumbs through [cueenv.Override], never os.Setenv, so LoadDir is safe under concurrency.
Keeping this routine single-sourced guarantees an overlay-built artifact and an on-disk artifact are evaluated, shape-gated and error-wrapped identically: the only difference between the acquire verbs is where the package files come from.
Types ¶
type ArtifactSpec ¶
type ArtifactSpec struct {
Label string
ExpectedKind string
RequiredConcreteFields []string
ModuleRefs []ModuleRef
// CompleteEntryMaps lists paths to maps whose every entry must be
// complete: each regular field of each entry validates under
// cue.Concrete(true). An absent map passes. Used for #Platform.#registry,
// where core derives an entry's `version` from the catalog the entry
// embeds (enhancement 0019 D5), so an entry with no embedded catalog is
// incomplete exactly where the catalog would have completed it.
CompleteEntryMaps []string
}
ArtifactSpec describes the shape gate for one artifact type. ExpectedKind is the concrete kind literal the package must carry; RequiredConcreteFields are dotted paths to scalar identity fields that must be present and concrete; ModuleRefs point at embedded #Module values whose kind must in turn be "Module". Label names the artifact in filesystem-level error messages.