📄 shadow.py 5,293 bytes May 02, 2026 📋 Raw

"""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}")