Skip to content

Environment identity, reuse, and rebuilding

Wetlands reuses an environment only when it can prove that the ready environment matches the requested recipe.

Recipe identity

The normalized EnvironmentSpec, supplied lockfile digest, local package settings, and Wetlands-managed worker runtime contribute to recipe identity. Changing any of them requires a rebuild rather than silently using a different environment.

Ready publication

Provisioning performs dependency resolution, installation, post-install commands, and runtime validation before publishing ready metadata. The environment becomes usable only after that final publication succeeds.

If provisioning fails or is canceled, Wetlands removes the incomplete target. If the host crashes, the next provisioning attempt detects missing or inconsistent ready metadata and rebuilds instead of resuming unknown state.

Lockfiles

Without pixi_lock, Pixi resolves the generated project and Wetlands keeps the resulting pixi.lock in the managed environment.

With pixi_lock, Wetlands installs exactly from the supplied lock and rejects changes during provisioning. The lock must match the complete generated project, including local packages and Wetlands' managed runtime dependencies.

Replacement strategy

replace_existing=True removes an existing different recipe before the new recipe is ready.

Applications that require rollback should put a release or recipe identity in the managed environment name, provision the new name, and update their own logical mapping only after success.

See Discover, replace, and remove environments for the relevant calls.

Installed runtime content

A ready environment exposes environment.runtime_content_receipt() without starting a worker or subprocess. The immutable RuntimeContentReceipt provides content_digest and a detached to_scientific_facts() dictionary. Its scientific facts include the actual interpreter identity, installed Python distribution versions and member-content digests, resolved Conda artifact facts, and admitted editable source digests. generation_id, recipe_hash, and lockfile_hash are separate operational fences; they do not salt the scientific content digest. Consequently, equal admitted content under different owned prefixes or generation IDs can share a content identity, while changed installed local-package content differs even when the requested recipe and lockfile are unchanged.

Provisioning captures installed content after validation and before ready publication. An installed Conda distribution is admitted through one installed Conda manifest that owns its exact Python metadata anchor. That installed inventory takes precedence over an upstream wheel RECORD, which may still describe entry points transformed by the Conda installer. Distributions without an installed Conda owner must provide a complete RECORD. Conda admission matches the public metadata location, text, name, and version, and captures the complete owning package inventory, including owned data outside the Python package directory. The same captured member inventory governs installed hashing and editable activation admission; missing or ambiguous ownership refuses capture. Recorded operational bytecode caches may be absent, but missing retained source or data members refuse capture before ready publication. It streams installed members once; warm receipt reads validate the stored owner and generation binding without rescanning installed package bytes. Generated bytecode, installation bookkeeping, direct URL paths, and verified editable activation paths do not become scientific content. Normalization does not remove arbitrary paths embedded in executable source, data, or native binaries. Different installer relocations of native binaries may therefore retain different content identities; Wetlands does not certify native relocation equivalence. Resolved Conda artifact metadata records installer selection, not a complete independent byte attestation of every native dependency. The receipt covers normal Wetlands-owned provisioning and does not certify external manual mutation of installed files or arbitrary Python process state.

Editable packages retain an explicit live-source boundary. Owned activation metadata and actual import membership determine bounded source roots, including Hatch src layouts without top_level.txt. Each receipt admission checks those roots against their captured source and data content, rejecting symlink escapes and changed source with EditableRuntimeSourceChangedError. Close the old workers and explicitly recreate the environment before executing changed source. The getter does not hot reload modules, remove environments, or seal editable files against later editing. Applications may memoize one receipt admission within an owned operation; a later operation must admit again.

EnvironmentManager.environment(name) inspects ready state without creating lifecycle lock directories or changing files. Missing, incomplete, or inconsistent ready state is unavailable rather than an invitation to provision during inspection. A ready generation created without this receipt cannot supply runtime content authority; explicitly recreate it when that authority is required. Starting, spawning, provisioning, and removing still enforce the lifecycle gate and current generation.