# DHA Core — Codebase Review **Repo:** NightKnight64/dha-core **Reviewed:** 2026-04-25 **Location:** `/home/hoffmann_admin/dha-core-legacy` **Size:** 10 Python files, 716 lines total **State:** Archived / deprecated — superseded by `family-assistant` and `hoffdesk-agents` --- ## 1. Architecture DHA Core is an **abstract service mesh framework** — not a shipping family assistant. It defines a plugin architecture where modules implement a `DHA_Module` ABC, are registered via `Service_Manifest.yaml`, and executed by an `Orchestrator` with an in-process `BackgroundScheduler`. There's an EventBus for pub/sub between modules and a YAML-based identity/role system. ### Component Map (716 total lines) ``` ┌─────────────────────────┐ │ Service_Manifest.yaml │ (4 services) └─────────┬───────────────┘ │ ┌─────────▼───────────────┐ │ Orchestrator.py (161) │ ── YAML loader │ │ ── Dynamic import + init │ │ ── APScheduler loop └─────────┬───────────────┘ │ ┌───────────────────────┼───────────────────────┐ │ │ │ ┌───────▼───────┐ ┌────────▼───────┐ ┌─────────▼──────┐ │ Persistence │ │ Identity │ │ CalendarSync │ │ Module (105) │ │ Module (95) │ │ Module (98) │ │ - SQLite │ │ - household.yaml│ │ - Adapter │ │ - state save │ │ - RBAC │ │ Pattern │ └───────┬───────┘ └────────┬───────┘ └─────────┬──────┘ │ │ │ │ ┌─────────▼───────┐ ┌─────────▼──────┐ │ │ Notification │ │ GoogleAdapter │ │ │ Module (44) │ │ (simulated) │ │ │ - EventBus │ └────────────────┘ │ │ subscriber │ │ └─────────┬───────┘ │ │ └───────────────────────┘ EventBus (12 lines) Supporting infrastructure: ├── DHA_Module.py (22) ── Abstract Base Class ├── event_bus.py (38) ── Pub/Sub (in-memory) ├── debug_smore.py (28) ── Debug launcher └── smore_test.py (100) ── Integration test / demo ``` ### Architecture Assessment ✅ **Good abstraction, poor implementation** The abstract framework is well-conceived: - Plugin pattern via ABC + YAML manifest → genuinely extensible - EventBus provides loose coupling - Adapter pattern for calendar providers (though only Google is implemented and it's mocked) - `background.Scheduler` for recurring tasks But it's **all scaffolding and no building**: - The Google adapter returns **hardcoded mock data** - The Notification module just prints to terminal - The Identity module loads from YAML but never checks permissions in a real request - No real API endpoints, no Telegram/webhook integration - `Service_Manifest.yaml` is in `.gitignore` (intentionally omitted for deployment) --- ## 2. Code Quality ### What's Good - **Clean abstract interface.** `DHA_Module` with `initialize()`, `check_status()`, `execute_task()` is a solid contract. - **EventBus is minimal and correct.** 38 lines, no external deps, works. - **`smore_test.py` is a working integration test.** It spins up the orchestrator, initializes all four modules, runs a loop — genuine end-to-end smoke test (albeit with mocked adapters). - **`__pycache__` is gitignored.** Small win, but consistent. ### What's Not - **Google adapter returns hardcoded fake data.** The comment says "Simulated API call" — this is a stub, not production code. The `api_key` config parameter is accepted but never used. - **No actual HTTP/API layer.** No FastAPI, no Flask, no webhook. DHA Core can't receive or send anything — it's a local-only scheduler with `print()` statements as output. - **`sys.path.append` in every module.** All four modules have the exact same boilerplate: `sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))`. Should be a one-line setup.py / PYTHONPATH fix. - **`household.yaml` includes Maggie the dog as a `standard` role user.** Cute, but the RBAC layer has a canine member with `preferences.notifications: false` — which is correct, but it's an indication the design is playful rather than production. - **`smore_test.py` has `time.sleep(4)` polling.** The scheduler should call back; blocking sleeps are not how you test an event loop. - **No error recovery.** If a module fails to initialize, the orchestrator logs it but continues. No circuit breaker, no retry, no alert. - **The `PersistenceModule` saves JSON state but nothing reads it.** It's write-only storage. --- ## 3. Feature Completeness vs What It Should Have Been | Feature | Status | Family Assistant Equivalent | |---------|--------|---------------------------| | Plugin module system | ✅ **Built** | Not needed (single app) | | EventBus pub/sub | ✅ **Built** | Not used | | YAML identity + RBAC | ✅ **Built** | YAML config in config.py | | Calendar fetch (Google) | 🔶 **Stubbed** | 660 lines, Radicale CalDAV | | Notification | ❌ **print() only** | 602 lines, Telegram Bot API | | Email parsing | ❌ Missing | 1148-line pipeline | | LLM extraction | ❌ Missing | appointment_parser.py | | Conflict resolution | ❌ Missing | 415-line conflict_engine.py | | Webhook / HTTP | ❌ Missing | 252-line email_webhook.py | | Family Brain / RAG | ❌ Missing | 495-line family_brain.py | | Clicker / slot tracking | ❌ Missing | 303-line clicker.py | | Maintenance reminders | ❌ Missing | 376-line maintenance_sentinel.py | | Tests | 🔶 1 integration demo | 1 test file (test_qa.py) | --- ## 4. Relationship to Family Assistant DHA Core was the **prototype** that taught you the patterns that became Family Assistant. Specifically: - **Learned:** Abstract module frameworks (DHA_Module) add complexity without value for a single-app deployment. Family Assistant doesn't use it — it's a flat Python package. - **Learned:** Hardcoded adapter patterns (GoogleAdapter) are worse than YAML-driven config. Family Assistant uses `config.py` with env vars and family.yaml. - **Learned:** In-process EventBus is overengineered for a notification system that just needs HTTP. Family Assistant uses direct Telegram API calls. - **Learned:** The plugin manifest adds deployment friction without the benefit of hot-plugging. Family Assistant is a pip-installable package. The calendar_sync module in DHA Core (98 lines, mocked) became the 660-line radicale-driven `calendar_sync.py` in Family Assistant. The identity module (95 lines, YAML-only) became the `config.py` family.yaml loader (369 lines with env, caching, dynamic grading). The notification module (44 lines, `print()`) became `hermes.py` (602 lines, Telegram Bot API). **DHA Core is best understood as a "proof of concept" that you evolved past.** The architecture decisions (service mesh, abstract modules, EventBus) are the right patterns for a multi-service distributed system, but for a single-machine family assistant they were overengineering. --- ## 5. Portability: 5/10 - **Requirements:** `PyYAML==6.0.3` (+ Python stdlib). That's it. - **No external deps:** No FastAPI, no httpx, no Ollama, no CalDAV libraries, no databases beyond SQLite. - **BUT:** It doesn't *do* anything useful without external services. The Google adapter is stubbed. There's no webhook to receive events. The notification module doesn't connect to anything. - **Verdict:** Portable by virtue of being incomplete. Running it gives you a scheduler that prints to stdout. --- ## 6. Assessment Summary | Dimension | Score | Notes | |-----------|-------|-------| | Architecture Concept | 8/10 | Abstract module system is well-designed | | Actual Implementation | 3/10 | All adapters stubbed, no real I/O | | Code Quality | 6/10 | Clean ABC, but sys.path.append everywhere | | Feature Completeness | 2/10 | Framework only, no shipping features | | Portability | 5/10 | Minimal deps, but useless without wiring | | Evolution Value | 7/10 | Taught valuable lessons that shaped Family Assistant | ### Historical Significance This was the **original blueprint** — the architecture you sketched before you wrote a single line of Family Assistant. The fact that it evolved into a 10k-line working system that processes real email, syncs to a real calendar, and runs on your hardware is genuinely impressive. The DHA Core framework (Service_Manifest, DHA_Module ABC, EventBus) was the right starting point, and Family Assistant is the right destination. **Recommendation:** Delete the `dha-core` GitHub repo or archive it with a clear README note that says "Historical prototype — superseded by NightKnight64/family-assistant." The abstract framework is interesting but misleading as a starting point for anyone who finds it. --- # Family Assistant (Standalone) — Codebase Review **Repo:** NightKnight64/family-assistant **Reviewed:** 2026-04-25 **Location:** `/home/hoffmann_admin/.openclaw/workspace/scripts` (+ cloned in `hoffdesk-agents/services/family_assistant`) **Size:** ~10,385 lines across 24 Python modules + 7 prompt files + `pyproject.toml` **State:** **Production.** Serving real traffic via Cloudflare webhook on `hook.hoffdesk.com`. --- *Note: This is the same codebase reviewed in-depth in `hoffdesk-agents-review.md`. The key findings are summarized here with a focus on differences from the mono-repo copy.* ## Key Finding: Near-Identical to `hoffdesk-agents` Version The standalone `family-assistant` repo and the version embedded in `hoffdesk-agents/services/family_assistant` are essentially the same code: - **22 of 24 Python files are byte-for-byte identical** - `hermes.py` differs (standalone: 602 lines, mono-repo: 666 lines — likely OpenClaw integration hooks) - `pipeline.py` differs by 1 byte (trivial) - Same prompts, same tests, same structure **However**, the standalone repo has important artifacts that the mono-repo doesn't: - `systemd/` directory with actual service files (`family-assistant-webhook.service`, `hoffdesk-webhook.service`, `radicale.service`) - `WEBHOOK_DEPLOY.md` — deployment docs for the Cloudflare Worker - `email_worker.js` — the Cloudflare Email Worker that routes mail to the webhook - `LICENSE` (MIT) — the mono-repo doesn't have one - `backup_hoffdesk.sh` — backup script - `.env` file (real credentials — **still live**) - Legacy wrappers (`family_calendar.py`, `fetch_unread.py`) ### Critical Finding: `.env` is Committed-Adjacent The `.env` file in the standalone repo (`/home/hoffmann_admin/.openclaw/workspace/scripts/.env`) contains: - `GMAIL_APP_PASSWORD` (live Gmail password) - `GOOGLE_PLACES_API_KEY` (live) - `CALDAV_PASSWORD` (Radicale credentials) - `TELEGRAM_BOT_TOKEN` (live bot token) - `WEBHOOK_SECRET` (live webhook shared secret) - `OLLAMA_EMBED_URL` (hardcoded to Gaming PC Tailscale IP) - `OPENAI_API_KEY` (if configured) It's gitignored, but it **lives inside the tracked project tree**. The `hoffdesk-agents` version has the same `.env` in `services/.env`. If you ever clone with `--include-untracked`, force-push a branch that includes it, or accidentally stage it with `git add .`, those credentials are in git history permanently. **Recommendation:** Rotate all six credentials, then move `.env` to `~/.openclaw/secrets/family-assistant.env`. Update the systemd `EnvironmentFile` paths accordingly. --- ## Family Assistant vs DHA Core: The Evolution | Dimension | DHA Core | Family Assistant | |-----------|----------|------------------| | Philosophy | Abstract framework | Concrete application | | Architecture | Service mesh + EventBus | Flat package + direct calls | | Calendar | Google Calendar (mocked) | Radicale CalDAV (self-hosted) | | Email ingress | None | Cloudflare Webhook + IMAP fallback | | LLM | None | Ollama (qwen2.5-coder:7b) | | RAG | None | ChromaDB + nomic-embed-text | | Notification | print() | Telegram Bot API + inline buttons | | Tests | 1 integration demo | 1 smoke test (test_qa.py) | | Real users | 0 | 2 (Matt + Aundrea) | | Lines of Python | 716 | ~10,385 | | External API deps | 0 | 1 (Google Places — optional) | | Git commits | 5 | ~20 | The evolution is clear: **DHA Core taught you the patterns. Family Assistant built the product.** Both have near-zero test coverage and `sys.path`/import quirks, but Family Assistant actually ships real value. --- ## Key Findings Summary ### Critical (fix immediately) 1. **Rotate all credentials in `.env`** and move the file to `~/.openclaw/secrets/` 2. **`appointment_retry.txt` is empty** (0 lines) — the LLM retry path sends a blank prompt 3. **Gaming PC hardcoded** as the only embedding + vision host — if it's off, the Brain and document scanning break silently ### High Priority 4. **No tests for 23/24 modules** — any refactoring is blind 5. **Pipeline has ~500 lines of duplicated code** (IMAP path vs webhook path) 6. **`hermes.py` has dual notification paths** (direct Telegram API + OpenClaw subprocess) — potential for duplicate sends 7. **Family assistant standalone has a cleaner `.gitignore`** with `family.yaml`, `maintenance.yaml`, `chroma_db/`, `locations/`, and `auth_circuit_breaker.json` ignored — the mono-repo version should adopt these patterns ### What's Actually Great - **`config.py`** is production-quality: centralized, cached, dynamic family context injection - **`rrule_builder.py`** prevents LLM hallucination on recurrence rules (deterministic Python → RFC 5545) - **Circuit breaker** on IMAP auth failures prevents notification spam during outages - **Shadow filtering** (rejection_engine.py) events are demoted, not deleted — user sees what was filtered - **Prompt-as-Code** pattern — prompts in text files, not Python. Easy to iterate without touching code. - **Hybrid Retrieval** (calendar + ChromaDB) is the smartest architectural decision in the codebase