"""Icarus Shadow Mode Configuration — COMPLETELY ISOLATED.
Shadow mode is for silent observation only. The bot reads messages,
extracts entities, runs tripwire detection, and logs to shadow.db.
HARD CONSTRAINTS (non-negotiable):
- SPEAK_ENABLED = False (bot never sends messages)
- SHADOW_MODE = True (enables shadow behavior)
- Database: shadow.db (isolated from staging/production)
- Family context: Real Hoffmann family data
This configuration is used when ENV=shadow.
"""
import os
from pathlib import Path
Environment
ICARUS_ENV = "shadow"
ICARUS_VERSION = "0.0.1"
---------------------------------------------------------------------------
SHADOW MODE FLAGS (HARD DISABLES)
---------------------------------------------------------------------------
SPEAK IS HARD-DISABLED. The bot will NEVER send messages.
This is a safety constant, not a configuration option.
SPEAK_ENABLED = False
SHADOW_MODE = True
Safety assertions — fail fast if these are wrong
assert not SPEAK_ENABLED, "CRITICAL: SPEAK_ENABLED must be False in shadow mode"
assert SHADOW_MODE, "CRITICAL: SHADOW_MODE must be True"
---------------------------------------------------------------------------
Data paths (ISOLATED from staging and production)
---------------------------------------------------------------------------
DATA_DIR = Path(os.environ.get("DATA_DIR", Path.home() / ".icarus" / "shadow"))
SHADOW_DB_PATH = DATA_DIR / "shadow.db"
EXPORT_DIR = DATA_DIR / "exports"
LOG_DIR = DATA_DIR / "logs"
Ensure directories exist
DATA_DIR.mkdir(parents=True, exist_ok=True)
EXPORT_DIR.mkdir(parents=True, exist_ok=True)
LOG_DIR.mkdir(parents=True, exist_ok=True)
---------------------------------------------------------------------------
Telegram (staging bot token, but different group)
---------------------------------------------------------------------------
TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")
TELEGRAM_GROUP_ID = os.environ.get("TELEGRAM_GROUP_ID") # Family Logistics group
Shadow mode bot info
TELEGRAM_BOT_USERNAME = "hoffdesk_staging_bot" # Staging bot username
---------------------------------------------------------------------------
Ollama (Gaming PC via Tailscale)
---------------------------------------------------------------------------
OLLAMA_BASE_URL = os.environ.get(
"OLLAMA_BASE_URL",
"http://matt-pc.tail864e81.ts.net:11434"
)
OLLAMA_PRIMARY_MODEL = os.environ.get("OLLAMA_PRIMARY_MODEL", "qwen2.5-coder:7b")
OLLAMA_UTILITY_MODEL = os.environ.get("OLLAMA_UTILITY_MODEL", "llama3.2:3b")
OLLAMA_EMBED_MODEL = os.environ.get("OLLAMA_EMBED_MODEL", "nomic-embed-text")
LLM endpoints for extraction
LLM_URL = f"{OLLAMA_BASE_URL}/v1/chat/completions"
LLM_MODEL = OLLAMA_PRIMARY_MODEL
---------------------------------------------------------------------------
Family Context (REAL HOFFMANN FAMILY)
---------------------------------------------------------------------------
FAMILY_CONFIG_PATH = os.environ.get(
"FAMILY_CONFIG_PATH",
str(Path(file).parent.parent / "family_context.yaml")
)
The shadow bot uses real family data:
- Matt (dad)
- Aundrea (mom)
- Sullivan/Sully (son)
- Harper (daughter)
- Maggie (dog)
---------------------------------------------------------------------------
Shadow Mode Behavior
---------------------------------------------------------------------------
Tripwire threshold (0.0 - 1.0)
Messages scoring above this trigger LLM extraction
TRIPWIRE_THRESHOLD = 0.4
Minimum confidence for auto-validation
MIN_EXTRACTION_CONFIDENCE = 0.7
Export settings
DAILY_EXPORT_TIME = "23:59" # UTC time for daily export
EXPORT_RETENTION_DAYS = 30
Polling settings
POLLING_TIMEOUT = 60 # seconds
POLLING_BACKOFF = 5 # seconds on error
---------------------------------------------------------------------------
Admin DM for Enriched Shadow Mode
---------------------------------------------------------------------------
ADMIN_CHAT_ID = os.environ.get("ADMIN_CHAT_ID")
LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO")
LOG_FORMAT = "%(asctime)s - [SHADOW] - %(levelname)s - %(message)s"
---------------------------------------------------------------------------
Safety Checks
---------------------------------------------------------------------------
def _safety_check():
"""Verify shadow mode safety constraints."""
errors = []
if SPEAK_ENABLED:
errors.append("SPEAK_ENABLED must be False in shadow mode")
if not SHADOW_MODE:
errors.append("SHADOW_MODE must be True")
if DATA_DIR.exists():
# Check we're not accidentally pointing to staging/prod
if "staging" in str(DATA_DIR) and "shadow" not in str(DATA_DIR):
errors.append(f"DATA_DIR {DATA_DIR} appears to be staging, not shadow")
if "production" in str(DATA_DIR) or "prod" in str(DATA_DIR):
errors.append(f"DATA_DIR {DATA_DIR} appears to be production, not shadow")
if errors:
raise RuntimeError("SHADOW MODE SAFETY CHECK FAILED: " + "; ".join(errors))
Run safety check on import
_safety_check()
print(f"[SHADOW MODE] Initialized with DATA_DIR={DATA_DIR}")
print(f"[SHADOW MODE] SPEAK_ENABLED={SPEAK_ENABLED}, SHADOW_MODE={SHADOW_MODE}")