-
Notifications
You must be signed in to change notification settings - Fork 1
Concepts
This page defines nepenthe's vocabulary and how the pieces relate. Each term links to a deeper page where relevant.
nepenthe is environment-focused, not repo-focused. Where a tool like pixi locks the dependencies of one repository, nepenthe builds and distributes shared environments — curated collections of packages, often the union of many teams' needs — that are solved once, versioned, and installed across many repos and machines.
| Term | Meaning |
|---|---|
| Manifest | The declarative YAML description of one or more environments — channels, base dependencies, features, variants, and environments. See Manifests. |
| Feature | A named, composable group of dependencies (e.g. dev, ray). Environments select features. |
| Environment | A named composition of features for a set of platforms (e.g. app = dev + ray). Fans out over a build matrix. |
| Variant | A build flavor an environment selects (e.g. cpu vs gpu), carrying its own dependencies, solver constraints, and virtual-package overrides. |
| Override layer | A separate, pullable YAML file that adjusts a solve — version pins, variant constraints, virtual-package assumptions, and matrix exclude/include tables — without editing the manifest. See Manifests. |
| Channel | Where packages come from. Channel names in a manifest resolve to URLs via an alias and mirrors, so you can point at any server. See Channels & Artifactory. |
| Spec backend | Where specifications (manifests, overrides, locks) are read from / written to: file://, s3://, https://. See Storage Backends. |
| Lock | The frozen solve output — a rattler_lock lockfile. The primary, reproducible artifact. |
| Registry | A backend-hosted index mapping a (environment, platform, python, variant, version) to a content-addressed lock, enabling versioning and label resolution. See Registry & Versioning. |
An environment keeps one name and fans out over two axes:
-
variant — e.g.
cpu,gpu -
python — e.g.
3.11,3.12,3.13
Each (variant × python) combination is one build cell. A Selector picks
a cell; omitted axes fall back to declared defaults. Manifest::targets(env)
enumerates every cell (minus any pruned by the override exclude/include tables).
Resolving an environment unions, in order:
- base
dependencies(andpypi-dependencies), - every selected feature's dependencies (including those inherited via
extends), - the selected variant's dependencies, constraints, and virtual packages,
- the chosen python (injected as
python <ver>.*).
Conda and PyPI dependencies are kept separate throughout. The result is a
ResolvedEnvironment — a single build cell ready to solve.
The lock is the contract. Solving happens once, at publish time, against a pinned view of the channels. Installs read the lock and never re-solve, so every machine gets a byte-identical environment. Versioning happens at solve time, not install time.
A published lock is stored by its content address (sha256-<hex>), not by
its version. A version label points at a content address. This means:
- the same lock can back several versions (dedup),
- a published version never changes underneath you,
- rollback is just repointing a label,
- a pull recomputes the hash and rejects tampered bytes.
See Registry & Versioning for the full model.
nepenthe is currently a Rust library. The rust/examples/ directory has small,
runnable programs that exercise these concepts end to end:
cd rust
cargo run --example manifest_workflow # compose + resolve a manifest
cargo run --example e2e_from_yaml # load YAML fixtures → resolve → registry
cargo run --example registry_local # publish/resolve/pull versions locally
cargo run --example channel_override_artifactory # point channels at an internal ArtifactoryThis wiki is autogenerated. To made updates, open a PR against the original source file in docs/wiki.