CI checks out only the peregrine repo — ../circuitforge-core doesn't exist,
causing 'pip install -r requirements.txt' to fail.
requirements.txt now uses git+https://...@main as the fallback for CI and
bare pip installs. Dockerfile.cfcore installs cfcore from the local COPY
first (skipping the requirements.txt line) to avoid a redundant network
fetch during Docker builds.
Add pytest-playwright and pytest-json-report to requirements.txt; create
tests/e2e/ skeleton (modes/, pages/, results/) with __init__.py files and
.gitkeep; add results subdirs to .gitignore.
T8: compose.cloud.yml — multi-tenant cloud stack on port 8505, CLOUD_MODE=true,
per-user encrypted data at /devl/menagerie-data, joins caddy-proxy_caddy-internal
network; .env.example extended with five cloud-only env vars.
T10: app/telemetry.py — log_usage_event() is the ONLY entry point to usage_events
table; hard kill switch (all_disabled) checked before any DB write; complete no-op
in local mode; swallows all exceptions so telemetry never crashes the app;
psycopg2-binary added to requirements.txt. Event calls wired into 4_Apply.py at
cover_letter_generated and job_applied. 5 tests, 413/413 total passing.
cloud_session.py: no-op in local mode; in cloud mode resolves Directus JWT
from X-CF-Session header to per-user db_path in st.session_state.
get_connection() in scripts/db.py: transparent SQLCipher/sqlite3 switch —
uses encrypted driver when CLOUD_MODE=true and key provided, vanilla sqlite3
otherwise. libsqlcipher-dev added to Dockerfile for Docker builds.
6 new cloud_session tests + 1 new get_connection test — 34/34 db tests pass.
The package is never imported in the app — it was pulling torch + CUDA
(~7GB) into the main app container for no reason. AIHawk runs in its own
conda env (aihawk-env) outside Docker per design.
- preflight.py now writes PEREGRINE_GPU_COUNT and PEREGRINE_GPU_NAMES to
.env so the app container gets GPU info without needing nvidia-smi access
- compose.yml passes PEREGRINE_GPU_COUNT, PEREGRINE_GPU_NAMES, and
RECOMMENDED_PROFILE as env vars to the app service
- 0_Setup.py _detect_gpus() reads PEREGRINE_GPU_NAMES env var first;
falls back to nvidia-smi (bare / GPU-passthrough environments)
- 0_Setup.py _suggest_profile() reads RECOMMENDED_PROFILE env var first
- requirements.txt: add pdfplumber (needed for resume PDF parsing)