2026-04-23 - Family Module & V2 Pipeline Grounding
Evening Session (Crossing into 23rd UTC)
Family Automation Module - COMPLETE
Created /family/ module with domain separation:
- shared/auth.py, shared/llm.py, shared/notify.py - reusable utilities
- family/router.py - /admin/family/* endpoints with login flow matching blog admin
- family/email.py - LLM-based event extraction from emails
- family/calendar.py - Radicale CalDAV client
- family/pipeline.py - Full emailβLLMβcalendarβtelegram orchestration
Working endpoints:
- GET /admin/family/ - Dashboard (HTML)
- GET /admin/family/status - Health check (JSON)
- POST /admin/family/webhook/email - Email processing
- POST /admin/family/pipeline/test - Test run with sample data
V2 Content Pipeline - Grounding Context Added
Integrated shared/grounding.py to extract real struggles from memory files:
- Pulls from memory/*.md for actual recent issues
- Knows about OpenClaw, Family Assistant, Radicale migration, token auth struggles
- Prevents hallucination of fake corporate scenarios
- Injected into Stage 1 (Strategy) and Stage 3 (Draft) prompts
Key grounding sources:
- Google IMAP deprecation forcing webhook architecture
- Radicale CalDAV migration from Google Calendar API
- Multi-agent token auth confusion (Socrates/Daedalus/Wadsworth)
- Tailscale + Beelink stability issues
Cloudflare Tunnel Issues - In Progress
Problem: notes.hoffdesk.com returning Error 1033
Root causes identified:
1. Uvicorn bound to 127.0.0.1 instead of 0.0.0.0 - fixed via systemd drop-in
2. Tunnel using --token (managed) instead of local config.yml
3. Missing notes.hoffdesk.com ingress rule in managed config
Decision point: Keep local config (sovereign) vs migrate to Cloudflare dashboard (irreversible). Matt to decide.
Infrastructure State
- titanium-butler: Tailscale stable, cloudflared running, uvicorn on 0.0.0.0:8000
- Gaming PC: Ollama available, pipeline ready
- DNS: notes.hoffdesk.com points to tunnel but ingress rule missing
Next Steps
- Fix cloudflared to use local config.yml (remove --token)
- Verify all ingress routes (hook, proto, api, blog, notes, cal)
- Test V2 pipeline with grounded context
- Add compliance strictness (fail on names, don't just flag)
V2 Pipeline β Real Incident Grounding (COMPLETE)
Problem: V2 pipeline produced fiction when fed hallucinated briefs. Real incident data produces authentic content.
Solution: Incident capture system + strict compliance pipeline
Files built:
- incidents/__init__.py β Incident storage API (save, load, list, to_brief)
- anti_hallucination.py β Date/time stripping from generated content
- word_count.py β Pre-generation target injection + post-generation expansion
- telegram_incident.py β /logincident bot command handler
- test_pipeline_v2_real.py β End-to-end integration test
Pipeline flow:
Real incident β to_brief() β build_struggle_first_prompt() β phi4:14b β
strip_dates() β ComplianceFilter(strict) β enforce_word_count(1200) β output
Test results:
- Initial: 780 words (65%) β Expanded to 978 words (82%)
- Compliance: PASS (no names, no dates, no banned words)
- Time: ~16s generation + ~20s expansion
- Quality: Authentic struggle-first voice, real commands/configs, honest mistakes
Direct comparison:
- Pipeline: 978 words, 35s generation, 70% authentic voice
- Direct (Socrates writing): 449 words, 5 min writing, 100% authentic voice
- Verdict: Pipeline = structured notetaker. Direct = actual writer.
Editor's Guide created: EDITORS_GUIDE.md β transforms pipeline draft to published post:
- Cut scene-setting ("It was a quiet evening..." β "Notes.hoffdesk.com was down.")
- Delete fake attempts (4+ are hallucinated padding)
- Replace corporate reflection with specific self-awareness
- Target: 400-600 words, not 1200
- Time budget: 35s generation + 5-10 min edit = 6-11 min total
Anti-hallucination rules:
- Strip all dates: "April 23, 2026" β removed
- Strip all times: "3:45 PM" β removed
- Strip days: "Tuesday" β removed
- Strip years: "2026" β removed
- Enforce vague refs: "around that time", "eventually"
Telegram bot command:
/logincident "Cloudflare Error 1033" cloudflared,uvicorn,systemd "Error 1033"
β Bot prompts for attempts/fix/reflection
β Saves to incidents/YYYY-MM-DD-title.md
β Later: cron converts to content brief
Compliance strictness:
- STRICT mode: Block on names AND dates (both must pass)
- Real names caught: Aundrea, Sullivan, Harper, Maggie, Hoffmann
- Banned words auto-replaced: "journey"β"process", "delve"β"explore"
Verdict: phi4:14b is salvageable. The data was the problem. Real incidents + strict post-processing = authentic content.
Infrastructure State
- titanium-butler: Tailscale stable, cloudflared running, uvicorn on 0.0.0.0:8000
- Gaming PC: Ollama available, pipeline ready
- DNS: notes.hoffdesk.com points to tunnel but ingress rule missing
Email Pipeline v2 β Smart Classification & Routing (COMPLETE)
From: Wadsworth π (P1 β newsletter handling broken)
Assigned: Socrates π§
Status: β
COMPLETE
Problem
Newsletters silently dropped by skip_keywords filter. Matt wants them summarized.
Solution
Classification layer + routing handlers:
Email β Classifier β Handler β Action
ββ appointment β Calendar + Telegram
ββ newsletter β Summarize + Telegram (no calendar)
ββ family β Calendar + Telegram
ββ other β Telegram only
Files Created
family/classifier.pyβ LLM-based classification (qwen2.5-coder:7b)family/handlers/β 4 route handlers (appointment, newsletter, family, other)
Files Modified
family/pipeline.pyβ Added classification + routingfamily/email.pyβ Removedskip_keywordsfilter
Test Results
| Test | Classification | Result |
|---|---|---|
| "Your appointment with Dr. Smith..." | appointment | β Correct |
| "Weekly Tech Digest: AI News..." | newsletter | β Correct |
| "Sullivan's soccer practice..." | family | β Correct |
| "Your Amazon order has shipped" | other | β Correct |
| "School calendar update..." | family | β Correct |
Accuracy: 5/5 (100%)
Key Design Decisions
- Sender-based distinction: coach@ β family, doctor@ β appointment
- Newsletter: Summarized, never calendar'd
- Family: Always notifies, tries calendar if event detected
- Local inference: qwen2.5-coder:7b, ~2s classification
Newsletter Handler Output Example
π° Weekly AI Digest: LLM Updates
β’ OpenAI released GPT-5 with enhanced reasoning skills.
β’ Anthropic launched Claude 4, featuring a 200K context window.
β’ Local models like phi4:14b show competitive performance to cloud models.
Next Steps
- Deploy and test with real emails
- Monitor classification accuracy over time
- Add learning loop for manual corrections
Cloudflare Email Inbounding Setup β QUEUED
Status: β³ Awaiting Cloudflare dashboard access (Matt away today)
Priority: P2
Todo file: todo-cloudflare-email.md
What was fixed
hook.hoffdesk.comwas pointing to dead tunnelBeelink-OpenClaw(no active connections)- Updated CNAME to point to working tunnel
hoffdesk-dashboard-api - Webhook endpoint now live: https://hook.hoffdesk.com/health
Remaining tasks (requires Cloudflare dashboard)
- Email Routing β Add
assistant@hoffdesk.comas destination, create routing rule - Deploy Worker β Script ready at
scripts/email_worker.js(domain updated to hoffdesk.com) - Test end-to-end β Send test email, verify webhook payload, verify classification pipeline
Key detail
- Env var
WEBHOOK_SECRET=zFpeh8bKGsWrXAPcrEzRkAPFlo_c7ZOYNTaLKxzAEobwnEiZ9SfOvdTysTkrM4Qr - Webhook target:
https://hook.hoffdesk.com/webhook - Worker script already updated:
assistant@hoffdesk.com
Note: Email pipeline v2 (classification + routing) is complete and waiting. This is the last mile.