πŸ“„ MEMORY.md 21,906 bytes May 01, 2026 πŸ“‹ Raw

MEMORY.md β€” Long-Term Memory

Identity

  • I am Socrates 🧠 β€” Lead AI Systems Architect
  • Vibe: efficient, competent, dry humor. Jarvis energy.

Matt

  • Head of household: wife Aundrea, kids Sullivan & Harper, dog Maggie
  • Green Bay, WI β€” America/Chicago timezone
  • Values: security, zero-trust, doing things right before scaling

Infrastructure

  • titanium-butler (Beelink): Ubuntu 24.04, loopback-only gateway (port 18789), token auth
  • Primary model: ollama/glm-5.1:cloud β†’ fallbacks: kimi-k2.5:cloud, gemma4:latest, qwen2.5-coder:7b
  • Local Ollama at 127.0.0.1:11434 β†’ Ollama Pro cloud
  • OpenClaw features: Dreaming (3 AM CST), Active Memory (direct DMs), command-logger hook, lightContext heartbeat
  • Gaming PC (Tailscale 100.104.147.116): 12GB 3080 Ti
  • qwen2.5-coder:7b (default pipeline model), gemma4:latest, qwen3-vl:8b (vision/OCR), nomic-embed-text (embeddings)
  • Secrets: All in ~/.openclaw/.env and scripts/.env (chmod 600, gitignored, never pushed)
  • Telegram: DMs allowlisted (8386527252), family group allowFrom Matt only

Family Assistant β€” v1.0 Feature-Frozen

  • Repo: https://github.com/NightKnight64/family-assistant (MIT, PII scrubbed 2026-04-16)
  • Package: scripts/family_assistant/ β€” 18 modules, full docs in README
  • Config: scripts/.env (env vars) + scripts/family.yaml (gitignored) + ~/.openclaw/secrets/gcal-service-account.json
  • LLM parsing: qwen2.5-coder:7b on Gaming PC via LLM_URL β€” zero cloud tokens
  • Embeddings: nomic-embed-text on Gaming PC β†’ ChromaDB on Beelink (~/.family_assistant/chroma_db/)
  • Vision: qwen3-vl:8b on Gaming PC (Drop-Box only, keep_alive: 0)
  • Location cache: ~/.family_assistant/locations/known_locations.json (home-biased, 90-day TTL)

Key Pipelines

  • Emailβ†’Calendar: IMAP fetch β†’ LLM parse β†’ Google Calendar CRUD β†’ Telegram push (Hermes)
  • Intent Engine: Wake word/reply-to-bot β†’ LLM classification (calendar/question/chatter) β†’ execute or RAG or silence
  • Family Brain (RAG): ChromaDB semantic retrieval + Calendar keyword search β†’ LLM synthesis (retrieval-only)
  • Conflict Engine: Detect overlaps β†’ LLM resolution options β†’ Telegram inline buttons (SPLIT/REASSIGN/RESCHEDULE)
  • Rejection Engine: Natural language β†’ LLM rule β†’ shadow filter (downgrade, never delete) β†’ persistent in family.yaml
  • Maintenance Sentinel: Recurring tasks with intervals β†’ alert dedup β†’ Done buttons
  • Clicker + Slots: Jina Reader fetch β†’ LLM slot extraction β†’ inline buttons β†’ [REMINDER] calendar event on tap
  • Document Sorter: Telegram image β†’ OCR (qwen3-vl:8b) β†’ LLM classify β†’ Google Drive upload (flat year folders)

Hermes Routing (Trust Over Silence)

  • Family Group: appointments, reminders, actions, conflicts, newsletter digest, daily brief
  • Matt's DM: auto-filtered items, pipeline errors, system health, research results
  • Philosophy: silence = distrust; users need visual confirmation

Critical Design Rules

  • Date disambiguation: nearest logical future date (not distant future)
  • Conflict anti-nag: [Conflict_Ack] tags + dismiss button
  • Shadow filter: rejected items downgraded (low_relevance), never deleted
  • Intent guardrail: trigger-based ONLY (wake word/reply-to-bot), NO passive listening
  • Global error handler: all crashes β†’ DM stack trace, no silent deaths
  • HTMLβ†’text: stdlib only (html.parser), no BeautifulSoup/lxml
  • Pipeline idempotency: ChromaDB uses .upsert(), Calendar uses dedup
  • Year display: show year only when event year β‰  current year

Permanent Model Rules

  • βœ… qwen2.5-coder:7b β€” single model for ALL pipeline tasks (beat phi4:14b on quality + speed)
  • βœ… qwen3-vl:8b β€” vision/OCR only (Drop-Box), keep_alive: 0
  • β›” No home-assist model β€” ever
  • β›” No deepseek-r1 models β€” burn thinking tokens, fail JSON
  • β›” No qwen3:8b β€” thinking tokens can't be disabled, 3-13x slower

CLI Quick Reference

  • process [--dry-run] β€” emailβ†’calendarβ†’Telegram
  • upcoming [--hours N] β€” list calendar events
  • conflict-notify β€” scan + alert on new conflicts
  • intent --message '...' β€” parse + execute calendar mutation
  • maintenance β€” check recurring tasks
  • reject 'event' 'reason' β€” add rejection rule
  • brain-query --question '...' β€” RAG query
  • click --url '...' --context '...' β€” fetch signup slots

Radicale CalDAV β€” Self-Hosted Calendar (2026-04-18)

  • Radicale 3.7.1 on Beelink: 0.0.0.0:5232 (localhost + Tailscale)
  • htpasswd: /home/hoffmann_admin/.config/radicale/htpasswd β€” bcrypt, 3 users (matt, aundrea, assistant)
  • Rights: /home/hoffmann_admin/.config/radicale/rights β€” all-authenticated-read-write (private network)
  • Storage: /home/hoffmann_admin/.local/share/radicale/collections/
  • Family calendar: "family" (owned by assistant user)
  • Passwords: family-matt-2026, family-aundrea-2026, family-assistant-2026
  • calendar_sync.py completely rewritten: caldav+icalendar, zero Google API
  • All downstream modules updated: intent_engine, conflict_engine, conflict_notify, rejection_engine, slot_handler, cli
  • pipeline.process_webhook_email() wired: webhook β†’ LLM extraction β†’ Radicale write β†’ Hermes
  • Commit: a8f32d1 pushed

The Board β€” Triple-Agent Architecture (2026-04-20)

  • Socrates 🧠 β€” Backend, pipelines, infra, AI architecture (this is me)
  • Daedalus 🎨 β€” Frontend, UI/UX, design system, mobile
  • Wadsworth πŸ“‹ β€” Chief of Staff, routing, scheduling, general assistance
  • Matt β€” The Director. Sets priorities, approves designs, owns the domain.
  • Collaboration: Contract-first β€” I write API specs, Daedalus builds UI, Wadsworth routes and coordinates, Matt approves
  • Shared workspace: /home/hoffmann_admin/.openclaw/shared/ (api-specs/, design-tokens/, project-docs/)
  • Daedalus workspace: ~/.openclaw/workspace-daedalus/ (separate identity, same gateway)
  • Wadsworth workspace: ~/.openclaw/workspace/ (main agent, coordination hub)
  • Daedalus model: ollama/gemma4:26b (separate model for creative diversity)
  • Socrates model: ollama/kimi-k2.5:cloud (reasoning-focused for architecture)
  • Wadsworth model: ollama/glm-5.1:cloud (generalist, coordination)

Inter-Agent Comms Protocol

  • βœ… sessions_send or sessions_spawn for agent-to-agent messaging
  • ❌ NEVER use Telegram API to message agents (causes identity confusion)
  • shared/ directory for async file-based coordination
  • Telegram @mention for Boardroom discussions where Matt is present

Architecture Principles

  • Prompt-as-Code: Route messy human data to LLM, never regex
  • Tri-Node: Beelink = orchestration; Gaming PC = inference; Cloud = deep reasoning only
  • Zero-Trust: App Passwords > OAuth. localhost/Tailscale only. No global npm -g with native bindings.
  • Maintenance > Compute: A prompt is easier to update than a regex library
  • Contract-First: API spec β†’ UI mock β†’ approval β†’ real wiring (prevents race conditions)

OpenClaw Config (2026-04-18 Audit)

  • Active: Dreaming (3 AM CST), command-logger hook
  • Active Memory: DISABLED (2026-04-20) β€” was blocking responses on slow models, causing generic output. Config preserved with llama3.2:1b-instruct-q4_K_M for future local recall.
  • Heartbeat: lightContext + isolatedSession + activeHours 06:00-23:00 CST (~95% token savings)
  • Fallback chain: glm-5.1:cloud β†’ kimi-k2.5:cloud β†’ gemma4:latest β†’ qwen2.5-coder:7b
  • Logging: redactSensitive: "tools"
  • Experimental: sessionMemory (indexes session transcripts for recall)
  • Wiki: isolated vault at ~/.openclaw/wiki/main/
  • Agent health playbook: shared/project-docs/agent-health/troubleshooting-playbook.md
  • Critical lesson: Auto-failover can permanently override agent model at session level β€” causes identity loss. See playbook.
  • Bookmark: Check command-logger.jsonl size in ~1 month, add logrotate if needed

Roadmap

  • [x] v1.0 PENCILS DOWN (2026-04-17) β€” all core features shipped
  • [x] OpenClaw features audit β€” 5 quick wins applied (security, heartbeat, fallback, hooks, memory)
  • [x] Radicale CalDAV migration β€” Google Calendar API completely replaced (2026-04-18)
  • [x] calendar_sync.py rewrite β€” caldav+icalendar, all modules updated
  • [x] pipeline.process_webhook_email() β€” webhook β†’ Radicale writes (2026-04-18)
  • [x] Radicale running on Beelink (0.0.0.0:5232, htpasswd bcrypt, 3 users)
  • [x] systemd services β€” radicale.service + hoffdesk-webhook.service installed & running
  • [x] Cloudflare Email Worker β€” deployed, WEBHOOK_SECRET set, Email Routing active for assistant@hoffdesk.com
  • [x] Sovereign backup β€” daily tar to local + Gaming PC via Tailscale SSH
  • [x] Phone CalDAV setup β€” both Matt & Aundrea on assistant account via cal.hoffdesk.com
  • [ ] Auth failure circuit breaker (3 consecutive β†’ pause + alert)
  • [ ] Drop-Box Drive setup (Drive API + folder share + DRIVE_FOLDER_ID) β€” blocked on Google
  • [ ] Wire Telegram image interception for Drop-Box
  • [ ] Multi-calendar, Docker Compose, YAML prompts (deferred post-v1.0)
  • [x] Fix conflict_notify.py NameError (RESOLVED by calendar_sync rewrite)
  • [x] Get Aundrea set up to email family manager (CalDAV live, email worker live)
  • [x] Daedalus agent initialized β€” workspace, SOUL.md, IDENTITY.md, onboarding doc (2026-04-19)
  • [ ] Telegram bot token for Daedalus (Matt handling)
  • [x] Daedalus agent added to openclaw.json + bindings
  • [x] Wadsworth identity fix β€” added main agent to openclaw.json, reset contaminated session (2026-04-19)
  • Lesson: Never operate as Socrates through the main/default bot β€” it contaminates Wadsworth's session history with wrong identity context. Always use the Socrates bot for Socrates work.
  • [x] "The Hoffmann Board" Telegram group created
  • [x] API specs for Family Dashboard β†’ shared/api-specs/
  • [x] HoffDesk Family Dashboard MVP (calendar + health + quick-add)
  • [x] Blog module Phase 1+2 β€” Core API + Admin API complete (36/36 tests passing) (2026-04-20)
  • [x] Blog module Phase 3 β€” Static generation + deploy COMPLETE (2026-04-20)
  • [x] Blog module Phase 4 Backend β€” Admin preview + list endpoints, 41/41 tests (2026-04-20)
  • Added POST /admin/posts/preview β€” Markdownβ†’HTML live preview
  • Added GET /admin/posts β€” Admin list with ?status= filter (draft/published/archived/all)
  • Response doc: shared/project-docs/blog/phase-4-socrates-response.md
  • [x] LocalAI Content Engine β€” phi4:14b on Gaming PC (2026-04-20)
  • Sovereign Operator voice (technical, pragmatic, direct)
  • Banned words: delve, tapestry, moreover, leveraging, holistic, paradigm, synergy, etc.
  • Three endpoints:
    • POST /admin/generate/title β€” 3-5 title options from bullets
    • POST /admin/generate/expand β€” Bullet points β†’ prose (augmented drafting)
    • POST /admin/generate/seo β€” Excerpt, tags, meta description
  • [x] Blog module Phase 4 Frontend β€” Admin UI templates deployed 2026-04-22, API integration complete (requires service restart)
  • [ ] Restart hoffdesk-web service to activate new templates

Market Sentiment Briefing β€” Complete βœ… (2026-04-27)

System: Finnhub API integration for daily market sentiment briefing
Free tier: 60 calls/minute, 4 calls per ticker (quote, sentiment, recommendations, earnings)
Default watchlist: AAPL, MSFT, GOOGL, AMZN, TSLA, NVDA, META, JPM

Components

  • core/market/sentiment.py β€” Finnhub API client + briefing generator (246 lines)
  • core/handlers/market_briefing.py β€” Telegram command handlers (/briefing, /watchlist)
  • jobs/daily_briefing.py β€” Cron job entrypoint for scheduled delivery

Features

  • Daily briefing at 3:00 PM CT (market close)
  • On-demand via /briefing command
  • Watchlist management via /watchlist and watchlist TICKER ...
  • Signal detection: analyst consensus + insider sentiment
  • Alerts: earnings surprises >10%, analyst changes β‰₯2 buys

Commands

Command Description
/briefing Generate and send market briefing
/watchlist Show current watchlist
watchlist TICKER ... Update watchlist

Documentation

  • shared/project-docs/market-briefing-system.md β€” Full system docs

Icarus Project

Location: ~/.openclaw/workspace/services/icarus/
Status: Phase 5 (Real World)

Phase 5 Components

  • [x] Data Abstraction β€” hoffmann.yaml + deterministic inference engine
  • [x] System State View β€” API + HTML dashboard with HTMX polling
  • [x] Memory System Port β€” ChromaDB + embeddings, zero costco_route imports
  • [x] Recipe Toggle System β€” Extractor + database + Telegram handlers
  • [x] Market Sentiment Briefing β€” Finnhub API + daily briefing
  • [ ] Telemetry wiring (waiting on real email data)
  • [ ] UAT (waiting on Matt)

Blog Module Phase 4 Frontend β€” Deployed βœ… (2026-04-22)

Frontend: Daedalus templates + admin UI deployed to /home/hoffmann_admin/hoffdesk/blog/
Backend: Admin dashboard API endpoints added (/admin/stats, /admin/recent, /admin/posts, /admin/images)
Service: Running from workspace-socrates, needs reload for new routes
Tests: All API endpoints verified

Files Deployed

  • 7 Jinja2 templates β†’ /home/hoffmann_admin/hoffdesk/blog/templates/
  • Admin templates β†’ /home/hoffmann_admin/hoffdesk/blog/admin/templates/
  • Static CSS β†’ /home/hoffmann_admin/hoffdesk/blog/static/

API Endpoints Added

GET /admin/stats      β†’ Dashboard statistics
GET /admin/recent     β†’ Recent activity feed
GET /admin/posts      β†’ Admin post list with filtering
GET /admin/images     β†’ Image manager

Next Step

The running service is in /workspace-socrates/ directory. New routes are added there. Service needs a process restart to pick up new code:

pkill -f "uvicorn main:app" && cd ~/.openclaw/workspace-socrates/hoffdesk-api && nohup uvicorn main:app --host 127.0.0.1 --port 8000 &

Archived History

  • See memory/2026-04-15.md and memory/2026-04-16.md for detailed progress logs
  • Key outcomes already reflected in sections above
  • 2026-04-16 ## Family Assistant β€” Major Progress ### Response Handler Built - execute_resolution() in conflict_engine.py β€” split/reassign/reschedule actions - handle CLI command: family_assistant handle --option N [--dry-run] - Tested all three actions end-to-end against live calendar ### Package Refactor (Archimedes v4) - Monolith family_calendar.py β†’ family_assistant/ package (10 modules) - Externalized 3 prompts to text files with {today}, {family_members}, {nickname_rules} placeholders - Legacy wrapper preserved (3-line import shim) ### De-personalization (Archimedes v5) - Family members β†’ family.yaml (configurable per household) - Prompt injection via {family_members} and {nickname_rules} placeholders - Setup wizard: python -m family_assistant setup [--non-interactive] - family.yaml.example as public template ### Post-Archimedes Fixes - Service account key fallback chain (env var β†’ CWD β†’ ~/.openclaw/secrets/ β†’ ~/.config/family-assistant/) - .env auto-load in config.py for cron/heartbeat sessions - Created scripts/.env and scripts/family.yaml ## OpenClaw - Updated to 2026.4.15 - Removed unsafe ollama/gemma4:31b-cloud from fallbacks ## Heartbeat Setup - heartbeat:check β€” every 30 min, system/weather/disk checks - heartbeat:daily β€” 7:00 AM CST, security audit + memory/wiki maintenance + update check [score=0.803 recalls=8 avg=0.396 source=memory/2026-04-16.md:1-32]

    • Admin auth is CF Access at the edge β€” FastAPI trusts headers, no auth middleware needed ### Wired into main.py: - Blog router mounted at /api/blog with CORS updated for POST/PATCH/DELETE - Draft blog post seeded: the-night-i-broke-dns ### Test results: 36/36 passing - Public read: list, get, related, categories, tags - Admin write: create, update, delete (soft), publish, unpublish - Full workflow: createβ†’publishβ†’readβ†’updateβ†’archive ### Next: Phase 2 (Admin API + auth) and Phase 3 (static generation with Daedalus' templates) [score=0.801 recalls=8 avg=0.417 source=memory/2026-04-20.md:21-32]
  • 2026-04-15 β€” Day One ## Onboarding & Security Hardening - OpenClaw updated from 2026.4.11 β†’ 2026.4.14 - UFW firewall configured: default deny inbound, allow outgoing. SSH (22) + web UI (18789) on tailscale0 only, loopback allowed - Ollama on Gaming PC (100.104.147.116): bound to Tailscale IP only, not 0.0.0.0 - Beelink Ollama fixed: was crash-looping due to wrong OLLAMA_HOST override (pointed at Gaming PC IP instead of own). Fixed to 0.0.0.0:11434 - Two-tier model routing established: - ollama/glm-5.1:cloud β€” daily driver (Ollama Pro cloud via local proxy) - ollama-remote/gemma4 β€” lightweight tasks on Gaming PC 3080 Ti via Tailscale - Telegram group security (CRITICAL) fixed: added allowFrom: ["8386527252"] to group wildcard, per-group extensible for future - Security audit: 0 critical, 3 warn (all acceptable/by design) - Plugin integrity: openclaw-web-search now has pinned version + integrity hash ## Identity - I am Socrates 🧠 β€” head thinker, lead agent - Vibe: efficient, competent, dry humor (Jarvis energy) - Matt: household head, wife Aundrea, kids Sullivan & Harper, dog Maggie - Location: Green Bay, WI (CST) - Vision: multi-agent setup, I'm the first/coordinator ## Still Open - Sandbox/workspaceOnly settings before adding other users - Pinning plugin spec to exact version - Web UI access over Tailscale (port 18789 allowed but not tested) - node-llama-cpp local embeddings (deferred, using nomic-embed-text via Gaming PC) ## Email + Calendar Pipeline (Phase 2 β€” DONE) [score=0.834 recalls=7 avg=0.403 source=memory/2026-04-15.md:1-31]

    • Updated CNAME to point to working tunnel hoffdesk-dashboard-api - Webhook endpoint now live: https://hook.hoffdesk.com/health ### Remaining tasks (requires Cloudflare dashboard) 1. Email Routing β€” Add assistant@hoffdesk.com as destination, create routing rule 2. Deploy Worker β€” Script ready at scripts/email_worker.js (domain updated to hoffdesk.com) 3. 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. [score=0.825 recalls=5 avg=0.417 source=memory/2026-04-23.md:185-199]
  • Created /family/ module with domain separation: [score=0.806 recalls=0 avg=0.620 source=memory/2026-04-23.md:6-6]
  • Working endpoints: [score=0.806 recalls=0 avg=0.620 source=memory/2026-04-23.md:13-13]
  • Integrated shared/grounding.py to extract real struggles from memory files: [score=0.806 recalls=0 avg=0.620 source=memory/2026-04-23.md:20-20]
  • Key grounding sources: [score=0.806 recalls=0 avg=0.620 source=memory/2026-04-23.md:26-26]
  • Decision locked: Session cookies for browsers, Bearer tokens for machines. Documented at shared/project-docs/auth-unification.md [score=0.869 recalls=0 avg=0.620 source=memory/2026-04-24.md:5-6]
  • | Before | After | |--------|-------| | X-Admin-Token header | Session cookie (hoffdesk_session) | | ?token= query param | Session cookie (unified login) | [score=0.869 recalls=0 avg=0.620 source=memory/2026-04-24.md:10-13]
  • | X-Hoffdesk-Secret | Bearer token for API/webhooks | | /admin/family/login (dead route) | Wired to unified auth system | [score=0.869 recalls=0 avg=0.620 source=memory/2026-04-24.md:14-15]
  • | User | Password | Email | Roles | |------|----------|-------|-------| | matt | hoffdesk-matt-2026 | matt@hoffdesk.local | admin, editor | | aundrea | hoffdesk-aundrea-2026 | aundrea@hoffdesk.local | family | [score=0.869 recalls=0 avg=0.620 source=memory/2026-04-24.md:25-28]
  • Browser β†’ /auth/login β†’ Session cookie set β†’ 30 day lifetime [score=0.869 recalls=0 avg=0.620 source=memory/2026-04-24.md:33-33]
  • Automatic redirect to original page [score=0.869 recalls=0 avg=0.620 source=memory/2026-04-24.md:35-35]
  • All /admin/* routes check session cookie [score=0.869 recalls=0 avg=0.620 source=memory/2026-04-24.md:37-37]