-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenvironment.yml
More file actions
143 lines (134 loc) · 6.87 KB
/
Copy pathenvironment.yml
File metadata and controls
143 lines (134 loc) · 6.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# EROTICA development environment — the single source of truth for dependencies.
#
# mamba env create -f environment.yml
# mamba activate erotica
# pip install -e . --no-deps # the package itself only; see "Why pip appears" below
#
# WHY THIS FILE EXISTS
# --------------------
# Until 2026-08-02 the package was developed and tested in the mamba *base* environment,
# which also carries boto3, fastapi, alembic, streamlit and the conda tooling itself — 374
# packages against this file's ~40. That is not a reproducibility problem in the abstract: it
# means `provenance.py` recorded the versions of an environment nobody could recreate, and
# "the tests pass" was a statement about one laptop. A JOSS reviewer installing from
# `pyproject.toml` alone would have been running different code.
#
# THE RULE
# --------
# **Never install into base.** Never run the test suite, a validation sweep, or a doc build
# from base. `.claude/check-env.sh` enforces this by refusing the command; that guard exists
# because writing the rule down here is not the same as following it (methodology.md K.1.9).
#
# WHY PIP APPEARS AT ALL
# ----------------------
# Four dependencies have no conda-forge package, checked with `mamba repoquery search` on
# 2026-08-02: gaiadr3-zeropoint, asteca, gaiaunlimited, hr-selection-function. Everything else
# resolves on conda-forge and is pinned there. The pip block lives *inside* this file rather
# than in a separate `pip install` step so the environment stays reproducible from one command
# — that is the documented conda pattern, not a workaround.
#
# `pip install -e . --no-deps` installs only the package. `--no-deps` is load-bearing: without
# it pip re-resolves the whole tree and silently shadows the conda-forge builds with PyPI
# wheels, which is how a conda environment becomes unreproducible.
#
# PYTHON VERSION
# --------------
# 3.14, verified by solve rather than assumed. An earlier draft of this file said 3.13 "because
# hdbscan and numba are the binding constraint" — that was a guess and it was wrong. A dry-run
# solve of the full 389-package set on 2026-08-03 resolves cleanly on conda-forge, with a native
# `hdbscan 0.8.44 py314h2115a04_0` build. Reproduce the check before changing this line:
#
# mamba create -n _probe --dry-run -c conda-forge python=3.14 <every dependency below>
# ---------------------------------------------------------------------------------------------
# WHICH LOCAL ENV ACTUALLY RUNS THIS PACKAGE — audited 2026-08-04, because the answer surprised me
# and the wrong choice fails SILENTLY rather than loudly.
#
# erotica-bench erotica 0.1.0 (editable) + asteca 0.7.0 <- the only env that reproduces the
# published benchmark table
# cosmic NO erotica installed; asteca 0.6.9 <- prior sessions prescribed this one
# erotica does not exist locally, despite `name:` below naming it
#
# `cosmic` appears to work because `pytest` and the validation scripts are run from the repo root,
# which puts `erotica/` on sys.path via the current directory. `import erotica` from ANY other
# working directory fails there. And its asteca 0.6.9 exposes the same API as 0.7.0, so the
# benchmark runs to completion and silently reports a different `asteca_fastmp` baseline.
#
# Two failure modes with no error message between them. Use `erotica-bench` for anything that
# produces a number, or create the env this file declares.
# ---------------------------------------------------------------------------------------------
name: erotica
channels:
- conda-forge
- nodefaults # never silently pull from `defaults`; mixing channels breaks ABI
dependencies:
- python=3.14
# Floors are set to what the 2026-08-03 solve actually resolved, so a rebuild cannot silently
# regress to an older stack. Resolved versions on python=3.14, osx-arm64:
# numpy 2.4.6 | scipy 1.18.0 | pandas 3.0.5 | astropy 8.0.1 | scikit-learn 1.9.0
# matplotlib 3.11.1 | hdbscan 0.8.44 | optuna 4.9.0 | pymc 6.2.0 | pytensor 3.2.4
# arviz 1.2.0 | numpyro 0.21.0 | blackjax 1.6.2 | jax/jaxlib 0.10.2 | xarray 2026.7.0
# sphinx 9.1.0
# The mamba base environment this package was actually developed in was BEHIND on several of
# these — astropy 7.2.0 and pymc 6.1.0 among them.
# --- core (mirrors [project.dependencies] in pyproject.toml) ---
- numpy>=2.4
- scipy>=1.18
- pandas>=3.0
- astropy>=8
- scikit-learn>=1.9
- matplotlib>=3.11
- tqdm>=4.65
- dill>=0.3.8
- hdbscan>=0.8.44
- optuna>=4.9
- adjusttext>=1.4
# --- [bayes] ---
- pymc>=6.2
- arviz>=1.2
- xarray>=2026.7
- numpyro>=0.21 # the adopted NUTS backend: 2.71x faster than PyTensor NUTS, same answer
- blackjax>=1.6 # declared, but see tools/validation/pymc_blackjax_progress_bar_bug.md
- fast-histogram>=0.14
# ArviZ 1.x ships NO netCDF engine of its own. Without this, `az.from_netcdf` and
# `trace.to_netcdf` raise on a clean environment -- four call sites, including the provenance
# trace WRITER (provenance.py:164) and the published-trace reader (figures.py:70). It works in
# the old mamba `base` only because h5netcdf happens to be an unrelated leaf there, which is
# exactly the kind of accidental dependency a clean environment is meant to expose.
#
# h5py is declared EXPLICITLY, not left to h5netcdf. On PyPI h5py is an optional extra of
# h5netcdf (`h5py; extra == "h5py"`), so an engine can install with no backend and fail with
# "No module named 'h5py', backend not available" -- which is exactly what happened to CI on
# 2026-08-04. conda-forge's h5netcdf does pull h5py today, but relying on that is the same
# accidental-leaf mistake this comment already warns about. pyproject.toml uses
# `h5netcdf[h5py]`.
- h5netcdf
- h5py
# --- [dev] ---
# ruff replaced black + isort + flake8. It is what .pre-commit-config.yaml runs and what
# pyproject.toml's [dev] extra declares, so this file installing the old trio -- and NOT ruff --
# meant a conda-created env could not run the hooks that gate a commit. Fixed 2026-08-03.
- pytest>=8
- pytest-cov>=4
- ruff>=0.14
- mypy>=1.5
- pre-commit>=3
- nbstripout>=0.7
# --- [docs] ---
- sphinx>=7
- pydata-sphinx-theme>=0.15
- numpydoc>=1.6
- myst-parser>=2
- sphinx-copybutton>=0.5
- sphinx-design>=0.6
# --- not on conda-forge (verified 2026-08-02) ---
- pip
- pip:
- gaiadr3-zeropoint>=0.1.0
# >=0.7 and not >=0.6, kept in step with pyproject.toml's `asteca` extra. The published
# benchmark table was measured on 0.7.0. 0.6.9 exposes the SAME API, so it runs, raises
# nothing, and silently yields a different `asteca_fastmp` baseline -- the row every EROTICA
# claim is stated relative to. No failure signal exists to catch that, so the floor is the
# only guard. Raised 2026-08-04.
- asteca>=0.7
- gaiaunlimited>=0.3
- hr-selection-function>=1.0