# Configure Project Env

> Inspect this workstation and configure, repair, or reproduce a Python project environment with a conda-first backend (falling back to uv when conda is unavailable or explicitly required), a project-named environment, reusable package caches, parallel package fetching, GPU-aware PyTorch selection, and a runnable smoke test. Use when Codex is asked to configure dependencies, create an environment, continue environment setup, reproduce a repository, install GPU packages, resolve CUDA or nvcc issues, or run a project demo after setup on this machine.

- Skill: `songyw2003/configure-project-env` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add songyw2003/configure-project-env`
- Raw SKILL.md: https://api.skillmd.com/api/skills/songyw2003/configure-project-env/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: songyw2003 (https://skillmd.com/u/songyw2003)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/songyw2003/configure-project-env

---


# Configure Project Environment

Configure project-specific Python environments consistently while reusing the workstation's package caches. Conda environments must be named environments stored under Conda's configured `envs_dirs`, not prefixes inside the repository. Prefer conda when it is installed and functional; use uv when conda is unavailable or the repository explicitly requires the uv workflow. Prefer verified project requirements over guessed versions.

## Workflow

1. Read repository instructions such as `AGENTS.md`, `README*`, `pyproject.toml`, `uv.lock`, `requirements*.txt`, `environment.yml`, setup scripts, and documented demo commands.
2. Run `scripts/inspect_machine.sh` from this skill. Read `references/machine-baseline.md` when interpreting this workstation's output.
3. Determine the repository root and derive a lowercase filesystem-safe project slug from its directory or declared project name.
4. Select the backend before creating an environment:
   - If `conda --version` succeeds, use conda by default, even when uv is also installed.
   - If conda is unavailable or broken, use uv.
   - If the repository explicitly mandates uv or depends on a uv-only lock/workflow, honor that repository instruction and report the exception.
5. Name the environment `.conda-<project-slug>` for conda or `.venv-<project-slug>` for uv, unless the repository explicitly establishes another project-specific name. For conda, use the name with `--name` so Conda selects the configured default environment directory. Never use `--prefix` with a path inside the repository for the default conda workflow. Do not silently fall back to an unnamed shared environment.
6. Select the Python and dependency versions from the repository's constraints. Do not alter a required version merely to hit an existing cache entry.
7. Install or sync dependencies, preserving the project's package source rules. For conda, use its configured channels and package cache; for pip-only packages inside a conda environment, use that environment's interpreter. For uv, prefer a domestic PyPI mirror for ordinary packages when downloads are needed, while using the required PyTorch/CUDA index for GPU wheels.
8. Validate imports, GPU runtime visibility, and the documented demo or smallest meaningful smoke test. Continue through validation instead of stopping after package installation.
9. Report the selected backend, environment path, Python version, cache path, package-fetch settings, GPU/driver observations, `nvcc` status, exact verification command, and any sandbox-only limitation.

## Select and configure conda

When conda is selected, prefer a recent conda with the `libmamba` solver. Conda 23.10 and later normally include and default to the libmamba solver; do not force `--solver=libmamba` on an older installation unless that option is supported. The solver speeds dependency resolution; it is separate from package-download parallelism.

Conda can fetch package archives concurrently. Use a named environment, not a repository-local prefix. `conda create --name` and `conda env create --name` place the environment under the first configured `envs_dirs` entry, which is the default Conda location for named environments. Inspect the actual path with `conda env list` after creation. Use the configuration variables below for the current command or equivalent `.condarc` settings:

```bash
CONDA_FETCH_THREADS=8 \
CONDA_REPODATA_THREADS=8 \
CONDA_EXECUTE_THREADS=1 \
conda create --name "$env_name" python=<required-python> pip --yes
```

`CONDA_FETCH_THREADS` controls package downloads, `CONDA_REPODATA_THREADS` controls repodata work, and `CONDA_EXECUTE_THREADS` controls linking/copying files into the environment. Choose the fetch/repodata values based on bandwidth and CPU; keep execute threads conservative unless the disk is known to benefit. Parallelism is best-effort and does not guarantee a speedup on a slow mirror or disk.

For a conda project, prefer its environment specification or lockfile:

```bash
CONDA_FETCH_THREADS=8 CONDA_REPODATA_THREADS=8 CONDA_EXECUTE_THREADS=1 \
conda env create --name "$env_name" --file environment.yml --yes
```

For a requirements-based or pip-only project, create the conda environment first, then install through its interpreter:

```bash
CONDA_FETCH_THREADS=8 CONDA_REPODATA_THREADS=8 CONDA_EXECUTE_THREADS=1 \
conda create --name "$env_name" python=<required-python> pip --yes
conda run --name "$env_name" python -m pip install -r requirements.txt
```

For a named environment, reuse it with `conda env update --name "$env_name" --file environment.yml --yes` when the project specification changes. Do not confuse conda's `--copy` option with cache reuse. There is no general `conda copy` command:

- `conda create --clone <source-env> --prefix <target-env>` creates an exact clone of an existing local environment.
- `conda create --name <env-name>` creates a named environment under Conda's configured `envs_dirs`; this is the required default path behavior for this skill.
- Conda automatically reuses packages in its `pkgs_dirs` cache and normally hard-links files into environments when the cache and environment are on the same filesystem; it copies only when linking is not possible.
- `conda create --copy` forces file copies and usually increases disk use; use it only when links are incompatible with the target filesystem or application.

Keep `envs_dirs` and `pkgs_dirs` on the same mounted filesystem when possible. Inspect the active locations with `conda config --show envs_dirs pkgs_dirs` and report them. Do not manually edit the package cache.

## Create the environment

For a conda project, set a project-specific name and let Conda choose the installation directory:

```bash
project_slug="<derived-project-slug>"
env_name=".conda-${project_slug}"
conda config --show envs_dirs pkgs_dirs
CONDA_FETCH_THREADS=8 CONDA_REPODATA_THREADS=8 CONDA_EXECUTE_THREADS=1 \
conda create --name "$env_name" python=<required-python> pip --yes
conda env list
```

Use `conda run --name "$env_name" ...` for commands in this environment. Do not derive `env_name` from a repository path or pass a repository path to `--prefix` unless the user explicitly requests a Conda prefix environment.

For a uv project, make the project-specific environment explicit when uv is selected:

```bash
project_slug="<derived-project-slug>"
env_dir=".venv-${project_slug}"
UV_CACHE_DIR="$HOME/.cache/uv" uv venv "$env_dir" --python <required-python>
UV_CACHE_DIR="$HOME/.cache/uv" UV_PROJECT_ENVIRONMENT="$env_dir" uv sync
```

For uv requirements-based or legacy projects:

```bash
UV_CACHE_DIR="$HOME/.cache/uv" uv venv "$env_dir" --python <required-python>
UV_CACHE_DIR="$HOME/.cache/uv" uv pip install --python "$env_dir/bin/python" -r requirements.txt
```

Use `uv pip sync` instead of `install` when the input file is intended to describe the complete environment. Keep cache and environment on the same filesystem when possible so uv can use clone/hardlink installation rather than copying.

## Handle GPU and CUDA

- Re-detect hardware on every run; treat the baseline as context, not eternal truth.
- When `nvidia-smi` fails inside Codex but PCI and `/proc/driver/nvidia/version` identify the GPU and driver, report sandbox GPU isolation and ask for or provide a command to run in the user's terminal. Do not conclude that the host driver is broken solely from the sandbox failure.
- Install GPU-enabled PyTorch when the project needs GPU support. Match the project's Torch version, Python ABI, platform, and CUDA source/channel. Use a cached compatible package when available automatically through the selected conda or uv cache. If the required GPU build is only available as a wheel, install it with the conda environment's interpreter while keeping conda as the environment backend.
- Verify runtime capability with the environment's interpreter:

```bash
if [ "$backend" = "conda" ]; then
  conda run --name "$env_name" python -c 'import torch; print(torch.__version__); print(torch.version.cuda); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else "GPU unavailable")'
else
  "$env_dir/bin/python" -c 'import torch; print(torch.__version__); print(torch.version.cuda); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else "GPU unavailable")'
fi
```

- Distinguish the NVIDIA driver from the CUDA toolkit. PyTorch GPU wheels can run without a system `nvcc`; building custom CUDA extensions cannot.
- This workstation has no system `nvcc` in the recorded baseline. If a project builds CUDA extensions, first inspect its supported toolkit version. Use a repository-local CUDA toolkit/sidecar when appropriate, set `CUDA_HOME`, `PATH`, and `LD_LIBRARY_PATH`, and verify `nvcc --version`. Do not claim extension support until compilation/import succeeds.
- Never switch to a CPU-only path just because the Codex sandbox cannot access `/dev/nvidia*`.

## Reuse and diagnose the cache

Use these read-only checks for whichever backend is selected:

```bash
conda info --envs 2>/dev/null || true
conda config --show envs_dirs pkgs_dirs 2>/dev/null || true
conda info --json 2>/dev/null | rg '"(pkgs_dirs|envs_dirs|platform|conda_version)"' || true
```

For uv, use:

```bash
UV_CACHE_DIR="$HOME/.cache/uv" uv cache dir
UV_CACHE_DIR="$HOME/.cache/uv" uv cache size
env | rg '^(UV_CACHE_DIR|UV_PROJECT_ENVIRONMENT|UV_PYTHON_INSTALL_DIR|XDG_CACHE_HOME)='
```

Use `--offline` only to prove that all exact artifacts are cached. Retry normally if an uncached dependency or metadata entry is needed. Never run `conda clean --all`, `uv cache clean`, or manually edit either cache unless the user explicitly requests cleanup. Use `uv cache prune` only with user authorization when cleanup is actually requested.

## Finish with evidence

At minimum, run:

```bash
if [ "$backend" = "conda" ]; then
  conda run --name "$env_name" python --version
  conda run --name "$env_name" python -m pip --version 2>/dev/null || true
else
  "$env_dir/bin/python" --version
  "$env_dir/bin/python" -m pip --version 2>/dev/null || true
fi
```

Then run relevant imports and the repository's documented demo or smoke test. If sandbox GPU isolation prevents the final CUDA test, finish all safe setup work and give the user one exact terminal command for the remaining verification.

