📄 ENRICHED-SHADOW-SPEC.md 7,379 bytes May 02, 2026 📋 Raw

Enriched Shadow Mode — Architecture Spec

Version: 2.0
Status: Approved for Implementation
Date: 2026-05-02


Parameter Lock (Director Constraints)

Constraint Value Enforcement
Speak Policy Strict Mute SPEAK_ENABLED=False hard-coded, never overridden
Calendar Access Read-Only calendar.readonly scope at API credential level
Query Trigger Event-Driven Only on Tier 1 tripwire fire
Auto-Write Prohibited Even confirmed actions only log to staging.db
Exhaust Channel Admin DM Proposed actions sent to Matt's private Telegram DM

Flow Diagram

Family Chat Message
        
        
┌───────────────────┐
 Tier 1: Tripwire  │── Score  0.4? ──► Log silently (done)
 (regex/keywords)  
└───────────────────┘
         Yes
        
┌───────────────────┐
 Tier 2: LLM       │── Extract who/what/when/where/confidence
 Extraction        
└───────────────────┘
        
        
┌───────────────────┐
 [NEW] Calendar    │── Query Google Calendar (readonly)
 Validation        │── Fuzzy match event title
 (Event-Driven)    │── Check person/time/location overlap
└───────────────────┘
        
        ├─ MATCH ───► Log: "Would have confirmed existing event"
                      (No DM needed, silent)
        
        ├─ NO_MATCH ─► Admin DM: "I would have added [Sully Pickup] 
                      to calendar for tomorrow 8 AM. Accurate? [Yes] [No]"
                       [Yes]  Log to staging.db (not real calendar)
                       [No]   Log to staging.db with rejection flag
        
        └─ CONFLICT ─► Admin DM: "Calendar shows 'Sully haircut' at 9 AM,
                       but message says 8 AM. Which is correct? [9 AM] [8 AM]"
                        Either answer  Log to staging.db for tuning

Google Calendar Integration

API Scope

  • Required: https://www.googleapis.com/auth/calendar.readonly
  • Forbidden: calendar (read-write), calendar.events
  • Enforcement: OAuth consent screen + API key restrictions

Query Strategy

# Event-driven only — called from shadow_bot.py after Tier 2 extraction
calendar.check_event(
    date_range=(extracted_date - 1 day, extracted_date + 1 day),
    query_text=extracted_what,  # "Sully haircut"
    family_member=extracted_who,  # "Sully"
)

Fuzzy Matching

  • Event title similarity ≥ 0.6 (fuzzy string match)
  • Date overlap (same day)
  • Optional: time overlap if extracted

Admin DM Exhaust Format

NO_MATCH Alert

🔍 Shadow Mode  Proposed Calendar Action

Message: "I've got Sully tomorrow"
Extracted: Pickup Sully, tomorrow, unspecified time
Calendar:  No matching event found

I would have added:
  📅 "Sully Pickup"  tomorrow (all day)

Accurate? [Yes] [No] [Edit]

⚠️ This is a simulation. Your calendar has not been modified.

CONFLICT Alert

🔍 Shadow Mode — Calendar Conflict Detected

Message: "Sully's haircut at 8"
Extracted: Sully haircut, tomorrow 8:00 AM
Calendar: ✅ "Sully Haircut" — tomorrow 9:00 AM

Conflict: Time mismatch (8 AM vs 9 AM)

Which is correct?
[📅 Keep Calendar: 9 AM]
[💬 Use Message: 8 AM]
[❓ I'm Not Sure]

⚠️ This is a simulation. Your calendar has not been modified.

MATCH Confirmation (Silent — No DM)

Logged silently to staging.db:
  "Sully pickup" — matched existing event "Sully Pickup" (tomorrow 3 PM)
  Action: None needed

Staging Database Schema Update

-- Add calendar validation columns to shadow_extractions
ALTER TABLE shadow_extractions ADD COLUMN calendar_check_status TEXT;  -- match | no_match | conflict
ALTER TABLE shadow_extractions ADD COLUMN calendar_event_id TEXT;       -- Google Calendar event ID
ALTER TABLE shadow_extractions ADD COLUMN calendar_event_title TEXT;   -- Matched event title
ALTER TABLE shadow_extractions ADD COLUMN calendar_event_time TEXT;    -- Matched event time
ALTER TABLE shadow_extractions ADD COLUMN admin_dm_sent BOOLEAN DEFAULT FALSE;
ALTER TABLE shadow_extractions ADD COLUMN admin_response TEXT;         -- yes | no | edit | timeout
ALTER TABLE shadow_extractions ADD COLUMN would_have_written BOOLEAN; -- What we would have done

Implementation Plan

Phase Task Owner ETA
1 Read gog skill for calendar.readonly auth Wadsworth 15 min
2 Add CalendarValidator class to shadow_bot.py Socrates 30 min
3 Implement fuzzy matching logic Socrates 45 min
4 Add Admin DM exhaust (Telegram DM routing) Wadsworth 30 min
5 Update staging.db schema Socrates 15 min
6 Integration test with real calendar queries Wadsworth 20 min
7 Deploy and monitor Wadsworth 10 min

Security Safeguards

API Credential Scoping

{
  "client_id": "...",
  "scopes": ["https://www.googleapis.com/auth/calendar.readonly"],
  "restrictions": {
    "allowed_ips": ["Tailscale IPs only"],
    "rate_limit": "100 queries/day"
  }
}

Write Protection

  • gog skill must fail if write scope requested
  • Code review: No events.insert() or events.update() calls in shadow mode
  • Runtime check: Assert readonly in token scope before any query

Rate Limiting

  • Max 1 calendar query per tripwire fire
  • Max 50 queries/day total (Google quota protection)
  • Exponential backoff on 429 errors

Metrics to Track

Metric Why
Calendar match rate How often extractions match existing events
False positive rate How often NO_MATCH alerts are rejected by Matt
Conflict resolution Which source Matt trusts more (calendar vs message)
Admin response time How quickly Matt replies to DM exhaust
Daily query volume Stay under Google's radar

Failure Modes

Scenario Behavior
Google API 429 Skip calendar check, log "API rate limited"
Token expired Skip calendar check, alert Wadsworth in logs
Calendar unavailable Skip check, treat as NO_MATCH (safe default)
Fuzzy match ambiguous Log both candidates, treat as CONFLICT
Admin DM timeout (5 min) Log "timeout", default to no action

Files to Modify

File Change
services/icarus/core/observer/shadow_bot.py Add CalendarValidator class, integrate into flow
services/icarus/core/observer/shadow_database.py Add calendar columns to schema
services/icarus/core/observer/shadow_telegram.py Add Admin DM exhaust method
services/icarus/calendar_adapter.py [NEW] Google Calendar wrapper (readonly)
services/icarus/shadow.env Add calendar credentials path
services/icarus/requirements-shadow.txt Add google-api-python-client

Approved by: Matt (Director)
Date: 2026-05-02
Next Action: Wadsworth to read gog skill, then dispatch Socrates for implementation