# Staging Environment Specification ## Overview Icarus Family Assistant supports dual environments (staging vs prod) with environment-variable-driven configuration. This enables safe testing of the Brain Query Interface and future features with dummy data (Miller family) before touching real family data (Hoffmann family). ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ ENV Variable │ │ staging (default) │ prod │ ├─────────────────────────────────────────────────────────────┤ │ config_env.py │ │ DB_PATH ~/.icarus/staging/staging.db │ │ ~/.icarus/data/prod.db │ │ CHROMA_DB_PATH ~/.icarus/staging/chroma_db │ │ ~/.icarus/data/chroma_db │ │ FAMILY_CONFIG ~/.family_assistant/family_staging.yaml │ │ ~/.family_assistant/family.yaml │ ├─────────────────────────────────────────────────────────────┤ │ Safety: _ensure_safe_paths() prevents staging→prod overlap │ │ Safety: staging_data.py exits if ENV!=staging │ │ Safety: startup_verify.py checks path isolation │ └─────────────────────────────────────────────────────────────┘ ``` ## Environment Variables | Variable | Staging Default | Prod Default | Description | |----------|----------------|--------------|-------------| | `ENV` | `staging` | `prod` | Environment mode | | `DB_PATH` | `~/.icarus/staging/staging.db` | `~/.icarus/data/prod.db` | SQLite database | | `CHROMA_DB_PATH` | `~/.icarus/staging/chroma_db` | `~/.icarus/data/chroma_db` | Vector store | | `FAMILY_CONFIG_PATH` | `~/.family_assistant/family_staging.yaml` | `~/.family_assistant/family.yaml` | Family YAML | | `GROCERY_LISTS_DIR` | `~/.icarus/staging/grocery_lists` | `~/.icarus/data/grocery_lists` | Grocery lists | | `RECIPES_DIR` | `~/.icarus/staging/recipes` | `~/.icarus/data/recipes` | Recipes | | `INGRESS_SPOOL_DIR` | `~/.icarus/staging/ingress_spool` | `~/.icarus/data/ingress_spool` | Ingress | | `VISION_CACHE_DIR` | `~/.icarus/staging/vision_cache` | `~/.icarus/data/vision_cache` | Vision | | `SEED_STAGING` | `0` | N/A | Set to `1` to auto-seed on startup | ## Safety Rules 1. **Default to staging** — If `ENV` not set, defaults to `staging` 2. **Path isolation** — `_ensure_safe_paths()` raises `RuntimeError` if staging paths overlap with prod 3. **No auto-seed in prod** — `staging_data.py` exits immediately if `ENV != staging` 4. **Startup verification** — `startup_verify.py` logs ENV and validates config before pipeline start 5. **Explicit opt-in** — `SEED_STAGING=1` required to auto-seed on startup ## Quick Start ### Staging ```bash export ENV=staging cd ~/hoffdesk-agents/services/family_assistant # Seed with Miller family test data (first time only) python -m family_assistant.staging_data # Run queries ENV=staging python -c " from family_assistant.family_brain import answer result = answer('Is Friday a half-day?') print(result['answer']) " ``` ### Production ```bash export ENV=prod cd ~/hoffdesk-agents/services/family_assistant # Start pipeline (uses existing Hoffmann data) python -m family_assistant.pipeline ``` ## Test Data (Miller Family) | Member | Role | Details | |--------|------|---------| | John Miller | Father | IT at local software company | | Sarah Miller | Mother | 3rd grade teacher, Lincoln Elementary | | Leo Miller | Son | Age 9, soccer + chess club | | Mia Miller | Daughter | Age 6, ballet + swim lessons | | Buster | Dog | Golden Retriever, 4 years | ### Test Queries | Query | Expected Answer | Source | |-------|----------------|--------| | "Is Friday a half-day?" | "No — full day per March 14 newsletter" | Newsletter | | "When is spring break?" | "March 24-28, 2026" | Newsletter | | "What time is Leo's soccer practice?" | "Tuesdays and Thursdays at 4:30 PM" | Soccer email | | "When was Buster's last vet visit?" | "February 20, 2026" | Receipt #4582 | ## Files Modified/Created ### Created - `config_env.py` — Environment-aware config with path isolation - `staging_data.py` — Miller family seeder (staging-only) - `startup_verify.py` — Pre-flight safety checks - `icarus.service` — Systemd service template - `tests/test_env.sh` — Environment isolation test - `STAGING_ENV.md` — User-facing docs - `~/.family_assistant/family_staging.yaml` — Miller family YAML - `~/.family_assistant/.env.staging` — Staging env template - `~/.family_assistant/.env.prod` — Production env template ### Modified - `config.py` — Added ENV awareness to family config resolution - `family_brain.py` — ChromaDB path now comes from `config_env.py` ## Verification Results ``` ✓ ENV=staging → staging paths ✓ ENV=prod → prod paths ✓ Staging DB != Prod DB ✓ Staging ChromaDB != Prod ChromaDB ✓ Staging paths isolated from production ✓ Staging DB_PATH points to prod → RuntimeError raised ✓ ENV=prod + staging_data → exits with error ✓ Miller family config loads correctly ✓ ChromaDB seeded with 4 test documents ✓ Query "Is Friday a half-day?" → top result: March Newsletter (0.612) ✓ Prod ChromaDB untouched (1.7MB, last modified Apr 28) ```