# 🎯 Icarus Phase 5 — 'Real World' Sprint **Director:** Matt (Veto Active: Path B, Hardware Procurement, SaaS Logic) **Sprint Goal:** Prove utility in real household before scaling **Timeline:** 2 weeks **Status:** APPROVED — Execute Immediately --- ## 📋 Scope (Modified Path A) | # | Component | Owner | Constraint | |---|-----------|-------|------------| | 1 | Data Abstraction | Socrates 🧠 | Single-tenant ONLY. No multi-family auth. | | 2 | System State View | Daedalus 🎨 | Read-only. No onboarding/editor UI. | | 3 | User Acceptance Testing | Matt (Director) | Live stress test with real documents. | **VETOED:** - ❌ Path B (multi-family, SaaS) - ❌ M4 Mac mini procurement - ❌ Multi-tenant authentication - ❌ Onboarding UI - ❌ Family self-service registration --- ## Component 1: Data Abstraction (Socrates) ### Deliverable: `hoffmann.yaml` + `family_loader.py` **File:** `icarus/config/families/hoffmann.yaml` ```yaml # Icarus Family Configuration — Hoffmann Household # Single-tenant: Hardcoded family_id="hoffmann" family_id: "hoffmann" version: "1.0.0" last_updated: "2026-04-26" members: - id: "sully" name: "Sullivan" nickname: "Sully" birthdate: "2019-05-15" current_grade: 1 school: "St. John's Elementary" teacher: "Mrs. Smith" interests: ["dinosaurs", "space", "lego"] calendar_color: "blue" - id: "harper" name: "Harper" nickname: null birthdate: "2021-03-22" current_grade: "pre-K" school: "St. John's Elementary" teacher: "Ms. Johnson" interests: ["unicorns", "dance", "art"] calendar_color: "pink" - id: "aundrea" name: "Aundrea" nickname: null relationship: "parent" workplace: "hospital" is_parent: true calendar_color: "purple" - id: "matt" name: "Matt" nickname: null relationship: "parent" workplace: "software" is_parent: true calendar_color: "green" inference_rules: - id: "rule_001" pattern: "first grade|1st grade|grade 1|Mrs\\. Smith" assign_to: ["sully"] confidence: 0.95 description: "Sully's grade level and teacher" - id: "rule_002" pattern: "pre-K|preschool|4 years old|Ms\\. Johnson" assign_to: ["harper"] confidence: 0.90 description: "Harper's grade level and teacher" - id: "rule_003" pattern: "parent-teacher|conference|both parents" assign_to: ["aundrea", "matt"] confidence: 0.80 description: "Events involving both parents" - id: "rule_004" pattern: "Sullivan|Sully" assign_to: ["sully"] confidence: 0.98 description: "Direct name mention" - id: "rule_005" pattern: "Harper" assign_to: ["harper"] confidence: 0.98 description: "Direct name mention" # Confidence thresholds telemetry: log_assignments: true log_confidence: true fallback_threshold: 0.70 ``` **File:** `icarus/core/family_loader.py` ```python """Family configuration loader — Single-tenant only.""" import yaml from pathlib import Path from typing import Optional from icarus.core.config.staging import DATA_DIR # SINGLE-TENANT: Hardcoded family DEFAULT_FAMILY_ID = "hoffmann" FAMILY_CONFIG_PATH = Path(__file__).parent.parent / "config" / "families" / f"{DEFAULT_FAMILY_ID}.yaml" class FamilyConfig: """Single-tenant family configuration.""" def __init__(self, family_id: str = DEFAULT_FAMILY_ID): """Load family configuration from YAML. Args: family_id: Must be "hoffmann". Single-tenant constraint. """ if family_id != DEFAULT_FAMILY_ID: raise ValueError(f"Single-tenant only. Family must be '{DEFAULT_FAMILY_ID}'.") self.family_id = family_id self._config = self._load_config() def _load_config(self) -> dict: """Load and parse YAML configuration.""" if not FAMILY_CONFIG_PATH.exists(): raise FileNotFoundError(f"Family config not found: {FAMILY_CONFIG_PATH}") with open(FAMILY_CONFIG_PATH) as f: return yaml.safe_load(f) @property def members(self) -> list[dict]: """Return all family members.""" return self._config.get("members", []) @property def inference_rules(self) -> list[dict]: """Return pattern matching rules.""" return self._config.get("inference_rules", []) @property def fallback_threshold(self) -> float: """Confidence threshold for asking user.""" return self._config.get("telemetry", {}).get("fallback_threshold", 0.70) def get_member(self, member_id: str) -> Optional[dict]: """Get member by ID.""" for member in self.members: if member.get("id") == member_id: return member return None def build_context_prompt(self) -> str: """Build family context string for LLM prompts.""" lines = ["FAMILY MEMBERS:"] for member in self.members: if member.get("current_grade"): # Kids only for school docs lines.append(f"- {member['name']} ({member.get('nickname', 'no nickname')}):") lines.append(f" Grade: {member['current_grade']}") lines.append(f" Teacher: {member.get('teacher', 'unknown')}") lines.append(f" School: {member.get('school', 'unknown')}") if member.get("interests"): lines.append(f" Interests: {', '.join(member['interests'])}") return "\n".join(lines) # Singleton instance _family_config: Optional[FamilyConfig] = None def get_family_config() -> FamilyConfig: """Get singleton family configuration. Single-tenant: Always returns Hoffmann family config. """ global _family_config if _family_config is None: _family_config = FamilyConfig() return _family_config ``` **Refactor: Update `briefing/generator.py`** Replace hardcoded `FAMILY_CONTEXT` with: ```python from icarus.core.family_loader import get_family_config family_config = get_family_config() FAMILY_CONTEXT = family_config.build_context_prompt() ``` --- ## Component 2: System State View (Daedalus) ### Deliverable: Read-only Dashboard **Route:** `/system/state` or `/admin/insights` **Display:** ``` ┌─────────────────────────────────────────┐ │ Icarus System State │ │ Family: Hoffmann │ ├─────────────────────────────────────────┤ │ Active Rules (5) │ ├─────────────────────────────────────────┤ │ Rule 001: first grade|1st grade... │ │ → Sully (95% confidence) │ │ Last triggered: 2026-04-25 14:30 │ │ │ │ Rule 002: pre-K|preschool... │ │ → Harper (90% confidence) │ │ Last triggered: 2026-04-25 09:15 │ ├─────────────────────────────────────────┤ │ Recent Routing Decisions (10) │ ├─────────────────────────────────────────┤ │ [✓] Pumpkin Patch → Sully (95%) │ │ [✓] Dentist → Sully (98%) │ │ [?] Community Event → Asked user │ │ [✓] Pre-K Graduation → Harper (92%) │ ├─────────────────────────────────────────┤ │ Confidence Distribution │ │ ████████████ High (>90%): 45 │ │ ████ Medium (70-90%): 12 │ │ ██ Low (<70%): 3 (user asked) │ └─────────────────────────────────────────┘ ``` **Requirements:** - ❌ NO editor, NO forms, NO buttons - ✅ Read-only visibility into system thinking - ✅ Shows YAML rules + real routing decisions - ✅ Confidence distribution histogram --- ## Component 3: User Acceptance Testing (Matt) ### Two-Week Trial Protocol **Daily:** 1. Forward real family emails to @IcarusTestBot 2. Upload PDFs, screenshots of forms 3. Note routing accuracy, confidence levels 4. Report false positives/negatives **Metrics to Track:** | Metric | Target | |--------|--------| | Correct routing (auto) | >90% | | Correct routing (user asked) | >95% | | Briefing quality score | >4/5 | | Time to briefing | <5 seconds | **Daily Log Format:** ``` Date: 2026-04-26 Documents tested: 3 - Field trip PDF → Sully (95%) ✅ - Dentist reminder → Harper (asked, correct) ✅ - Newsletter → No action (correct) ✅ Issues: None ``` --- ## 🚀 Execution Order ### Week 1 | Day | Task | Owner | |-----|------|-------| | 1 | Create `hoffmann.yaml`, `family_loader.py` | Socrates | | 2 | Refactor `briefing/generator.py` to use loader | Socrates | | 3 | System State view UI mock | Daedalus | | 4 | System State view implementation | Daedalus | | 5 | Integration test, validation | Wadsworth | | 6-7 | UAT begins (Matt starts daily testing) | Matt | ### Week 2 | Day | Task | Owner | |-----|------|-------| | 8-10 | UAT continues, data collection | Matt | | 11 | Mid-sprint review, adjust rules | All | | 12-13 | Rule refinement if needed | Socrates | | 14 | Sprint retrospective, Phase 6 planning | All | --- ## ✅ Success Criteria 1. ✅ `hoffmann.yaml` drives all family inference 2. ✅ System State view shows rules + routing decisions 3. ✅ UAT: >90% auto-routing accuracy 4. ✅ Zero multi-tenant code (validated by Wadsworth audit) 5. ✅ Real-world stress: 20+ documents processed --- ## 📚 Files Created/Modified | File | Action | Owner | |------|--------|-------| | `config/families/hoffmann.yaml` | Create | Socrates | | `core/family_loader.py` | Create | Socrates | | `briefing/generator.py` | Refactor | Socrates | | `admin/system_state.html` | Create | Daedalus | | `memory/2026-04-26-icarus-uat.md` | Daily logs | Matt | --- **EXECUTE. Modified Path A. Prove utility before scale.** --- *Questions: @mention Wadsworth in The Hoffmann Board*