The repos now sit directly under /srv/astrape, which is also every unit's
WorkingDirectory. Python prepends the working directory to sys.path for
'python -m', so the gibil checkout at /srv/astrape/gibil was shadowing the
installed package: the repo root has no __init__.py, so 'gibil' resolved as a
namespace portion with __file__ None, and submodules only resolved because a
namespace path recomputes itself on access.
Everything is installed into the venv, so nothing needs the working directory
on sys.path. WorkingDirectory still matters for env/ and models/.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Each repo carries the units for the daemons it owns. WorkingDirectory stays
/srv/astrape so env/ and models/ resolve, while the code comes from the
editable installs under repos/.
The old astrape-db.service was misnamed -- it runs the weather forecast
ingest, and collided with what would have been an astrape-db repo. It is
astrape-weather-forecast.service here.
The training unit forces ATEN_CPU_CAPABILITY=default, because this host has no
AVX2 and torch otherwise dies with SIGILL in Adam, and caps threads with Nice
so a nightly run does not starve the 5-second Modbus poll.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>