CLAUDE.md: document the requirements.py3.txt ↔ requirements-prod.lock relationship

Two-file dependency setup tripped me twice in one session:
  1. Added erldistpy to requirements.py3.txt without running make pins-lock.
     Result: env.tar.gz shipped without erldistpy, prod crypto_watcher
     hit ModuleNotFoundError at runtime.
  2. Added click as a CLI dep that wasn't in any pin file at all.
     Result: 516 import errors in CI tests across unrelated modules.

Documents the two-file model + the obligation to run `make pins-lock`
on every requirements.py3.txt edit. Notes the CLI-convention point too
(stdlib argparse, not click).
This commit is contained in:
russell@unturf.com 2026-06-17 07:45:29 -04:00
parent dd701fb319
commit 2905827c3f
No known key found for this signature in database

View file

@ -87,6 +87,42 @@ This project uses a Makefile for most development operations. Use `make` command
- Clean up environment: `make clean`
- Activate environment: `source env/bin/activate`
### Dependencies — two-file source of truth
Runtime deps live in **two** files; they are NOT redundant.
- `requirements.py3.txt` — what `setup.py` reads for `install_requires`.
Used by `pip install .` / editable dev installs. Source-of-truth for
what `make_post_sell` declares as its deps.
- `requirements-prod.lock` — hash-pinned, full transitive closure,
generated by `make pins-lock` (uv pip compile). What CI's
`install-source-prod` actually installs into `env.tar.gz` via
`pip install --require-hashes -r requirements-prod.lock`.
**Whenever you edit `requirements.py3.txt`, you MUST run `make pins-lock`
and commit the regenerated `requirements-prod.lock` in the same PR.**
If you forget: CI tests will still pass (test stage uses the unpinned
files), and the build artifact will still publish — but the artifact's
venv will be missing whatever dep you added. The deploy to prod will
silently roll out an env without the new dep. The first runtime import
of it is where the world finds out.
Pattern that has bitten us:
1. Add `erldistpy>=0.1.6` to `requirements.py3.txt`. Tests pass.
2. Forget `make pins-lock`. CI builds env.tar.gz from the stale lock.
3. Highstate ships → `pip show erldistpy` returns empty on prod →
`ModuleNotFoundError` the moment crypto_watcher reaches for it.
Same shape for any other dep — make a habit of running `make pins-lock`
after every requirements edit, before commit.
Same trap on the CLI side: if your new module imports a stdlib-adjacent
library that's not yet pinned (e.g. someone reaches for `click`
instead of `argparse`), it triggers `ModuleNotFoundError` in CI tests
because the CI runner's env doesn't carry the transitive. Match repo
convention (stdlib `argparse` for CLIs) before adding deps.
## Code Structure
### Key Directories