Files
hub_fixes/AGENTS.md

4.8 KiB

Hub Fixes

Catch-all for fixes and hardening to the Hub and the services that talk to it. Each directive below is a self-contained task. Run them one at a time.

Build spec for Paperclip. Follow each directive's DoD. Stop and ask if something is unclear.


1. Purpose and outcome

The Hub is live and the projects around it are running. This project fixes the things that break in that system — the failures that go unnoticed for days.

Outcome: when something in the voice/automation path dies, Sam finds out the same day — and the same class of bug cannot recur silently.

2. Scope

In scope

  • Watchdogs and alerting for the Hub and the voice path.
  • MQTT reliability across every client.
  • Firmware fixes for the ESP32 (in sam/voice_assistant).

Out of scope

  • New Hub features — those belong in central_ai_llm_master.
  • The workstream projects (email, school, internet control, Artemis).

3. Context — the outage this exists for

On 2026-10-13 the shared .13 Mosquitto restarted (internet-control added the 8883 TLS listener). Two things then failed silently:

  1. voice_bridge went deaf. It subscribed to MQTT once at startup with no on_connect handler. paho reconnected but never restored the subscription, so the bridge held a live socket with no subscription — no error, no log. Fixed 2026-10-14: added an on_connect re-subscribe.
  2. The ESP32 stopped publishing. Green LED (Wi-Fi joined) but nothing on voice/audio_stream. A power-cycle fixed it. Same bug class, still to do.

Neither was noticed for two days. Sam discovered it by talking to the house. That is the failure this project fixes.


Directive 1 — Voice intake watchdog (REQUIRED)

Requirement

  • Detect when voice intake is dead: no message on voice/audio_stream (.13 broker) for 15 minutes.
  • Send an alert via Apprise to Sam.
  • Repeat once a day while it stays broken. Not once — daily, until fixed.
  • The alert must say what failed and what to do:

    "Voice intake silent since HH:MM. Likely the ESP32 — try a power-cycle."

  • Do NOT auto-heal. No smart plug, no automatic power-cycling. Sam does that by hand. (This was considered and rejected — keep it a notification.)
  • Do not blame the ESP32 if something else broke. Check the broker and the bridge first, and say which layer failed.

DoD

  • Stop voice_bridge → an Apprise alert arrives within 15 minutes.
  • Leave it stopped → the alert repeats the next day, and the day after.
  • Start it again → the alerts stop.
  • Stop the broker instead → the alert names the broker, not the ESP32.

Directive 2 — MQTT reconnect rule (REQUIRED)

Every MQTT client in the lab must reconnect AND re-subscribe. paho reconnects on its own but does not restore subscriptions — the client then holds a live socket with no subscription and goes silently deaf.

Confirmed instances so far:

Client Status
voice_bridge ✅ fixed 2026-10-14 (on_connect re-subscribe)
ESP32 firmware ❌ to do — see Directive 3
Hub check
internet_use_control service check

DoD

  • Restart the .13 broker. Within 60 seconds, every client is receiving messages again — verified, not assumed.
  • Every client has an on_connect handler that re-subscribes, and logs when it does.

Directive 3 — ESP32 firmware (repo: sam/voice_assistant)

The unit shows green (Wi-Fi joined) while publishing nothing. Green is misleading.

  • Auto-reconnect MQTT and re-subscribe on every (re)connect.
  • Publish a heartbeat (e.g. every 5 min) so silence is a reliable signal — the watchdog in Directive 1 depends on this.
  • Show MQTT state on the LED. Green must mean connected and publishing, not merely on Wi-Fi.
  • Log the reason on the serial console when the broker connection drops.

DoD

  • Restart the broker. The ESP32 reconnects and publishes again within 60 seconds without a power-cycle.
  • Pull the Wi-Fi access point. The LED stops showing green.

4. Rules

  • Models go through OmniRoute. Secrets from environment.d.
  • Alerts go through Apprise (.35:8210).
  • Never change the .13 broker's 1883 plane — it is plain and anonymous, and n8n and the voice path depend on it. Kids' devices use 8883 only.
  • One commit and push per directive.
  • Bound every docker command (timeout, --entrypoint sh when running a shell inside an image).

5. Open questions

  1. Where does the watchdog live — a small service, or an n8n flow, or part of the Hub?
  2. Alert target: which Apprise channel (email / ntfy / WhatsApp)?
  3. How long should silence be tolerated before alerting? (Suggest 15 min.)
  4. Is the ESP32 on a smart plug anyway? (Still no auto-heal — but useful to know.)