1. System Architecture Updated: v4.0.34
status.json every 60 seconds and pushed to connected browsers via a persistent SSE connection with ~2s latency. No cloud dependency for core operation.2. Technology Stack Updated: v4.0.34
| Component | Version | Role |
|---|---|---|
| nginx | 1.26.3 | Reverse proxy, TLS termination, static file server, HA API + Pi-hole proxy |
| Python | 3.13.5 | All platform scripts — data collection, intelligence engine, briefing, backup, history |
| Home Assistant | 2026.4.3 | Smart home hub — device state, automations, presence detection |
| InfluxDB | OSS 2.x | Time-series metrics store. Bucket: greenacres. 11 measurements. |
| Grafana | Latest OSS | Metrics visualisation. 3 dashboards: server health, network, climate. |
| Mosquitto | Latest | MQTT broker for HA device integrations |
| Pi-hole | v6.5 | DNS-based ad/tracker blocking. HP (primary) + OP (secondary). Identical adlists. |
| Unbound | System | Recursive DNS resolver on OP (.20). Upstream for Pi-hole. |
| Debian | 13 “Trixie” | Host OS on both HP and OP |
| Linux kernel | 6.12.74+deb13+1 | amd64 on HP, ARM on OP |
| Docker | Latest CE | Container runtime. All services run in Docker on HP. |
| fail2ban | System | SSH brute-force protection. 1 jail (sshd) on HP and OP. LAN /23 whitelisted. |
3. Network & Hardware Updated: v4.0.34
| Host | IP | Hardware | Role | Resources |
|---|---|---|---|---|
| HP | 192.168.0.10 | HP MicroServer Gen8 | Primary server — all Docker services, nginx, platform scripts | 4 GB RAM · 456 GB disk · 21% used |
| OP | 192.168.0.20 | Orange Pi Zero | Secondary DNS server — Pi-hole + Unbound | 512 MB RAM · 3% disk |
| MWR | 192.168.0.1 | TP-Link ER7206 v1.0 | Gateway, router, Omada controller | — |
| SwitchA / SwitchB | — | TP-Link SG2210P v5.20 ×2 | PoE switching | — |
| HallwayAP | — | EAP653 (EU) v1.0 | Wi-Fi 6 AP — 2.4/5 GHz, channel 6 | — |
| LandingAP | — | EAP653 (EU) v1.0 | Wi-Fi 6 AP — 2.4/5 GHz, channel 1, 15 dBm TX | — |
| GardenAP | — | EAP650-Outdoor v1.0 | Outdoor Wi-Fi 6 AP — channel 6 | — |
| Starling Hub | 192.168.0.25 | Starling Home Hub | Google Nest bridge — cameras, thermostats (2), Protect via HomeKit | API key: /etc/starling.conf |
4. nginx Routing Updated: v4.0.34
/etc/nginx/sites-available/intranet-https.conf. Self-signed TLS. HA API token stored in nginx config — injected as Authorization header on proxy, never exposed to browser.| Port | Protocol | Serves |
|---|---|---|
| 443 | HTTPS / TLS | Hub — /srv/www/newsite/ |
| 8080 | HTTP | Monitoring portal — /srv/www/intranet/ |
| 80 | HTTP | Default server redirect |
| Location | Upstream | Notes |
|---|---|---|
/ha-api/ | 127.0.0.1:8123/api/ | HA REST API. Token injected server-side. Available on both :443 and :8080. |
/ask-cto | 127.0.0.1:8766/ask | Ask HAI AI backend. greenacres-ask-cto service. POST endpoint — accepts {question}, returns {ok, text} or {ok:false, offline:true}. |
/events/ | /srv/www/newsite/events/ | Event log viewer page. 90-day events.jsonl browsable with severity/category/time filters. |
/events.jsonl | /var/lib/greenacres/events.jsonl | Raw 90-day JSONL event log. nginx alias, no-cache. Consumed by /events/ page and Ask HAI. |
/grafana | 127.0.0.1:3000 | Grafana dashboard proxy |
/pihole/ | 127.0.0.1:8081/ | Pi-hole (HP) admin interface |
/api/ | 127.0.0.1:8081/api/ | Pi-hole (HP) v6 API |
/status.json | alias …/intranet/status.json | Cache-Control: no-cache. Both ports. |
/history.json | alias …/intranet/history.json | Cache-Control: no-cache. Both ports. |
/hai_briefing.json | alias …/intranet/hai_briefing.json | Cache-Control: no-cache. Both ports. |
/ | /srv/www/newsite/ | Hub root. All static HTML pages. |
5. Docker Stack Updated: v4.0.34
| Container | Port | Compose | Purpose |
|---|---|---|---|
| homeassistant | 8123 | /opt/homeassistant/ | Smart home hub. All device state, automations, presence. HA API consumed by greenacres_influx_write and /ha-api/ proxy. NET_ADMIN+NET_RAW for Bluetooth. |
| influxdb | 8086 | /opt/monitoring/ | Time-series DB. Bucket: greenacres. Receives 11 measurements at 60s intervals. |
| grafana | 3000 | /opt/monitoring/ | 3 dashboards: server health, network, climate. InfluxDB datasource. |
| mosquitto | 1883 | /opt/ha-services/ | MQTT broker for HA device integrations. |
| ha-filebrowser | internal | /opt/homeassistant/ | Web file browser for HA config. LAN-only. |
| ntfy | 8769 | /opt/ntfy/ | Self-hosted push notification server. Topic: greenacres-alerts. Auth: greenacres user. Proxied via nginx at /ntfy/. Used by intelligence engine for P1/P2 ntfy pushes alongside HA mobile notify. |
| matter-server | 5580 | /opt/homeassistant/ | python-matter-server: Matter protocol controller. WebSocket API on :5580. Used by HA Matter integration. Persistent state at /opt/matter-server/data/. Host network mode for mDNS discovery. Added v4.0.23. |
6. Systemd Services & Timers Updated: v4.0.34
| Unit | Schedule | Function |
|---|---|---|
greenacres-influx.timer | Every 60s | Collects HP vitals, OP vitals (SSH), Pi-hole stats (HP+OP v6 API), HA API state (locks, climate, presence, sensors), Starling Hub API (thermostats, cameras, Protect). Writes status.json and 11 measurements to InfluxDB. |
greenacres-metrics.timer | Every 60s | Writes /srv/www/arash/metrics.json for the /arash/ monitoring page. |
greenacres-intelligence.timer | Every 5 min | HAI engine: state durations, z-score anomaly detection (48h baseline / 6 sample minimum), cross-stream correlations, predictive trends (disk, battery). Detectors: duration, correlation, anomaly, trend, consumable (ink + Claude credits), HA restart, camera auto-recovery, occupancy context (SUGGEST-9), weather (TWIN-1: Open-Meteo 12h forecast, storm/rain/wind detection). Battery health predictor (SUGGEST-6): drain-rate model via linear regression, warns 14d out, alerts at 3d, covers patio/driveway cameras and front door lock. Occupancy context (SUGGEST-9): geofence + motion sensor model, confidence-rated (high/medium/low) with evidence list, enriches doorbell/night-motion/coverage-gap alerts. Alert deduplication (SUGGEST-10): 6h dedup window, per-alert snooze (4h/24h/7d) stored in snooze.json. Alert fatigue scoring: 14d lookback, top 10 noise sources. Structured logging (DEV15): always DEBUG to stderr/journald, per-detector counts, run summary. Pushes to iPhone via HA notify API and VAPID web push. Outputs Security/Comfort/Infrastructure health scores (0–100) + insights + battery_health + alert_fatigue + occupancy blocks in status.json. Sets /var/lib/greenacres/hai_escalate on alerts. |
greenacres-watchdog.timer | Every 5 min | Checks HP and OP reachability + Docker states. Mailjet email on failure. |
greenacres-history.timer | Every 15 min | Appends to history.json. 14 series, 30-day rolling (~672 pts/series at steady state). Points: [timestamp_ms, value]. |
greenacres-hai-morning.timer | 07:00 daily | Morning HAI Claude API briefing. Outputs to hai_briefing.json + hai_history.jsonl. Active — re-enabled v4.0.20. Template fallback when billing exhausted. |
greenacres-hai-evening.timer | 19:00 daily | Evening HAI Claude API briefing. Same output path. Active — re-enabled v4.0.20. Template fallback when billing exhausted. |
greenacres-hai-escalation.path | On flag file LAUNCH-GATED | systemd path unit watching /var/lib/greenacres/hai_escalate. Triggers Claude API escalation briefing. 2h cooldown (ESCALATION_COOLDOWN_S=7200) tracked in state_durations.json. Disabled — escalations consolidated into daily email at 12:00. Re-enable at agreed launch. |
greenacres-auth.service | Persistent | Session cookie auth service on 127.0.0.1:8768. Replaces nginx Basic Auth. Routes: GET /verify (internal auth check), GET /login (login page), POST /login (PAM for arash / htpasswd for legacy), GET /logout. 30-day cookie (ga_session), rate-limited 5 attempts/15min. python3-pam installed for Linux user auth. |
greenacres-sse.service | Persistent | SSE push server on :8765. inotify on status.json. Broadcasts to all browser clients. 60s poll fallback in browser. |
greenacres-backup | Daily 02:00 (cron) | Full snapshot: /srv/www, /opt/homeassistant, /opt/monitoring, /var/lib/greenacres, /etc configs. ~26 MB compressed. 5-day retention. flock-protected. |
maintain-all | Daily 04:00 | apt update + upgrade + autoremove on HP, then SSH to OP for same. |
greenacres-daily-email.timer | 12:00 daily | Single daily intelligence summary email to arash@foroozandeh.com via Mailjet SMTP. One Claude Haiku API call per day. Prompt caching on system prompt. Template fallback if credits exhausted. Styled GREENACRES INTELLIGENCE HTML email with headline, narrative, priorities, recommendation. Logs to events.jsonl + hai_history.jsonl. |
greenacres-automation-suggest.timer | Sunday 07:00 | Weekly automation suggestion engine. Calls Claude Haiku via Batch API (50% discount + prompt caching ≈ 75% total reduction). Generates 3–5 evidence-backed automation ideas from 14-day event patterns. Results in suggested_items.json, visible on /dev/ as Review queue. |
greenacres-camera-vision.timer | Every 5 min LAUNCH-GATED | Vision AI: Haiku analyses doorbell/driveway/garage1 camera snapshots. Detects people, packages, vehicles. Alert insights injected into intelligence engine. Disabled — re-enable at agreed launch when camera batteries replaced (2026-04-21). |
greenacres-morning-push.timer | 07:05 daily LAUNCH-GATED | iPhone push notification via HA notify. Disabled — replaced by daily email. Re-enable at agreed launch. |
7. Data Architecture Updated: v4.0.34
/srv/www/intranet/status.json (~18 KB). Served at /status.json on :443 and :8080 with Cache-Control: no-cache. Browser clients poll every 30s; SSE push delivers changes within ~2s.8. Security Updated: v4.0.34
| Control | Detail |
|---|---|
| TLS | Self-signed certificate. All hub traffic HTTPS :443. Port 80 is default-server only. |
| HA API token | Long-lived token in nginx config. Injected as Authorization header on /ha-api/ proxy. Never reaches browser. |
| Credential storage | /etc/omada.conf (Omada/SMTP/InfluxDB) · /etc/maintain-all.conf (HA token/SMTP) · /etc/hai.conf (Anthropic key) · /etc/starling.conf (Starling key). All root-readable only. |
| fail2ban | Active on HP and OP. 1 jail: sshd. Subnet 192.168.0.0/23 whitelisted. SSH key auth: ~/.ssh/id_ed25519. |
| Network boundary | No port forwarding. No external access. All services bound to 192.168.0.0/23. No VPN configured. |
| Audit trail | nginx access/error logs · systemd journal per service · HAI briefing history at /var/lib/greenacres/hai_history.jsonl. |
9. Storage & Backup Updated: v4.0.34
| Item | Detail |
|---|---|
| HP disk | 456 GB total · 87 GB used (21%) · /dev/sda2 |
| Daily backup | 02:00 daily · flock-protected · 5-day retention · ~26 MB per snapshot |
| Backup contents | /srv/www (hub+portal), /opt/homeassistant, /opt/monitoring, /var/lib/greenacres, /etc credential files |
| Backup location | /var/backups/greenacres/YYYY-MM-DD/ |
| HA native backup | Weekly Sunday 03:00. 4 copies retained. |
| HAI state files | /var/lib/greenacres/state_durations.json, baselines.json (rebuilt hourly), hai_history.jsonl |
10. File Reference Updated: v4.0.34
| Path (on HP unless noted) | Purpose |
|---|---|
| /srv/www/newsite/ | Hub root — 18 pages: home, status, events, analytics, controls, admin, releases, docs, docs/onboarding, ai, ai/releases, help (Ask HAI), dev, dev/history, backlog, dashboard, editor, go |
| /srv/www/intranet/index.html | Monitoring portal (~1905 lines, single-file, served on :8080) |
| /srv/www/intranet/status.json | Central state file. 60s write cycle. |
| /srv/www/intranet/history.json | 7-day time-series. 15-min append cycle. |
| /srv/www/intranet/hai_briefing.json | HAI briefing. 2×/day + on alert. |
| /usr/local/sbin/greenacres_influx_write | Main data collector → status.json + InfluxDB |
| /usr/local/sbin/greenacres-intelligence | HAI engine → health scores + insights |
| /var/lib/greenacres/push_sent.json | Per-alert push notification log. Prevents repeat pushes for persistent alerts. Pruned to active alerts on each intelligence run. |
| /var/lib/greenacres/weather_cache.json | 30-min Open-Meteo forecast cache. Written by intelligence engine (detect_weather_insights). Contains: condition summary, adverse/storm/rain/windy flags, max_precip_pct, max_wind_kmh, next12_temps, fetched_at timestamp. |
| /var/lib/greenacres/proposed_fixes.jsonl | SELF-1/2 fix queue. Each line: {id, ts, trigger_key, trigger_detail, proposed_action, action_type, action_params, confidence, status, status_updated, status_by}. Direct write (no atomic rename) per Landmine #10. Owned by greenacres-admin. |
| /var/lib/greenacres/sessions.json | Active auth sessions for greenacres-auth service. Format: {token: expiry_timestamp}. Written by root (greenacres-auth service). Pruned on each login. |
| /var/lib/greenacres/snooze.json | Per-alert snooze state. Written by admin-api (POST /snooze), read and pruned by intelligence engine. Format: {insight_id: {until, hours, reason, snoozed_at}}. Owned by greenacres-admin user. |
| /var/lib/greenacres/events.jsonl | 90-day rolling event log — alert/warn insights, pruned on each write. Read by Ask HAI for historical context. |
| /usr/local/sbin/greenacres-morning-push | Daily 07:05 intelligence briefing → iPhone push via HA notify. HP vitals, Docker, health scores, active insights. |
| /usr/local/sbin/greenacres-op-monitor | OP secondary monitor — HTTP server on 192.168.0.20:8080. Fetches HP status.json client-side. Fallback if HP web is unreachable. |
| /usr/local/sbin/greenacres-hai | Briefing generator (template or Claude API) |
| /usr/local/sbin/greenacres_history_write | 14-series history appender |
| /usr/local/sbin/greenacres_sse_server | SSE push server on :8765 |
| /usr/local/sbin/greenacres-release | Release automation script. Updates version badges on all 18 pages, adds release cards to /releases/ and /ai/releases/, updates /dev/ last-deploy note. Run at end of every deploy session. |
| /usr/local/sbin/greenacres-ask-cto | Ask HAI backend API. Python HTTP server on localhost:8766. Reads /etc/hai.conf for API key, loads status.json for system context, calls Anthropic API, returns JSON. Graceful offline state when credits depleted. |
| /srv/www/newsite/help/index.html | Ask HAI chat page at https://hp.lan/help/. Full chat UI — suggestion chips, typing indicator, AI online/offline status pill. |
| /usr/local/sbin/greenacres-watchdog | Container + server health watchdog |
| /usr/local/sbin/greenacres-backup | Daily backup script |
| /usr/local/sbin/maintain-all | Daily apt maintenance (HP + OP) |
| /usr/local/sbin/greenacres_stats (OP) | Remote stats helper, called via SSH by influx_write |
| /etc/nginx/sites-available/intranet-https.conf | nginx virtual host config |
| /opt/monitoring/docker-compose.yml | InfluxDB + Grafana |
| /opt/homeassistant/docker-compose.yml | Home Assistant + file browser |
| /opt/ha-services/docker-compose.yml | Mosquitto MQTT broker |
| /var/lib/greenacres/ | HAI state: state_durations.json, baselines.json, hai_history.jsonl, hai_escalate flag. Backlog: backlog.json (canonical dev tracking). AI suggestions: suggested_items.json. Events log: events.jsonl (90-day rolling) |
| /var/backups/greenacres/ | Daily backups, 5-day retention |
| /etc/omada.conf | Omada, SMTP (Mailjet), InfluxDB token |
| /etc/hai.conf | Anthropic API key (GA key active — claude-haiku-4-5-20251001) |
| /etc/starling.conf | Starling Hub API key |
11. Platform Release History Updated: v4.0.34
| Version | Codename | Date | Summary |
|---|---|---|---|
| v3.42.1 | Thornfield | 2026-04-13 | Admin page fix: system health tiles stuck on Loading — /status.json path corrected to /intranet/status.json |
| v3.42.6 | Thornfield | 2026-04-14 | JS lint gate in greenacres-release QA (node --check on admin page); Known Failure Modes landmines 13+14 added; /ai/releases/ hero updated to v3.8.0 |
| v3.46.0 | Thornfield | 2026-04-14 | HA-2 auto-lock: lock on away mode departure + 5-min unlocked auto-lock automation. HomeKit HASS Bridge disabled (removes duplicate Hue lights). Hue room group entities used directly in dashboard. |
| v3.47.0 | Thornfield | 2026-04-14 | Dashboard Lights view: replaced area cards with Hue self-maintaining room group entities (15 rooms + 6 garden zones + 6 scenes). Hue is source of truth, syncs automatically. |
| v3.50.0 | Thornfield | 2026-04-14 | Automation conflict resolution: 3 HA light automations disabled (hallway/landing/office) — Hue Bridge handles these. Fixed recurring AI Agent footer drift root cause: ai/releases hero card updated to v3.8.0. |
| v4.0.34 | Signal | 2026-04-23 | Hardening & stability: code review of 5 core scripts. 3 crash bugs fixed (ask-cto get_sov_mode NameError, intelligence severity ValueError, influx atomic write). PAM pam_lastlog.so removed from /etc/pam.d/login. logrotate policy added for all 7 greenacres logs. matter-server container added. Backup timer started. |
| v4.0.22 | Signal | 2026-04-23 | Crash fix: NameError in push_alerts_smart() (urgent/rotating_light bare names). PAM pam_lastlog.so silenced. Intelligence deduplication ValueError fixed. net_state.json atomic write. |
| v4.0.21 | Signal | 2026-04-23 | New P1 insight: Claude API billing exhausted — fires when Anthropic account has no credit balance. HAI writes flag file; intelligence reads it and alerts. HAI error handling improved (HTTP 400 body parsed). |
| v4.0.20 | Signal | 2026-04-23 | Occupancy-aware alert suppression (SUGGEST-10): P3/P4 non-security alerts silenced when house empty >2h. SOV-1/SOV-2 tiered model routing active at 50/80/95% credit. HAI timers re-enabled. |
| v4.0.19 | Signal | 2026-04-23 | Alert fatigue: fence/buddy/coverage-gap cameras permanently suppressed (intentionally offline). P3 72h auto-snooze. PHYS-2 7-day snooze. Intelligence debug log spam silenced. |
| v4.0.18 | Signal | 2026-04-21 | SOV-1: Ask HAI upgraded from Haiku to Sonnet (strategy model). Auto-downgrades to Haiku at 95% week usage; template fallback at credit exhaustion. |
| v4.0.17 | Signal | 2026-04-21 | BUG-RENDER-1 closed: /ai/ and /docs/ confirmed fully rendering in browser via Puppeteer MCP. Style tag fix (unclosed tags in ai/docs pages). Puppeteer MCP installed. |
| v4.0.30 | Signal | 2026-04-20 | V-P3 + NET-3: rclone backup script (greenacres-backup, weekly Sun 03:00) + NUT UPS pre-wired. All doc sections updated. |
| v4.0.15 | Signal | 2026-04-20 | CAP-5: ntfy.sh self-hosted push container on port 8769. Secondary push alongside HA mobile app for P1/P2 alerts. |
| v4.0.14 | Signal | 2026-04-20 | ENG-1: Laundry status + energy cost (28p/kWh) in portal Climate tab. CAP-8: all-device battery grid (28 sensors) in Security tab. |
| v4.0.12 | Signal | 2026-04-20 | CAP-4: Live camera snapshots in portal — all 5 online cams via HA proxy. Auto-refresh on status.json update. Bearer token injected server-side. |
| v4.0.11 | Signal | 2026-04-19 | Portal Batteries panel — all 28 devices colour-coded by tier (green/amber/red), sorted worst-first. Badge shows critical/low/ok counts. |
| v4.0.10 | Signal | 2026-04-19 | Credit alert false positive fix — unknown limit + extra_usage_enabled checks. Intelligence deduplication improved. |
| v4.0.9 | Signal | 2026-04-19 | SUGGEST-9: credit burn forecast + portal credit bar. Motion density dedup fixes. |
| v4.0.8 | Signal | 2026-04-19 | CAP-7: motion density + room temp trends in portal. Alert fatigue scoring. Vision timer re-enabled. |
| v4.0.5 | Vigilant | 2026-04-19 | matter-server fully decommissioned from all tracking. Bold lock batteries added to intelligence BATTERY_DEVICES. WiFi presence (binary_sensor.arash_wifi_home) feeds ha.presence in status.json. Stale Wemo OrangePi entity disabled. All platform scripts fixed for id-only backlog items. |
| v4.0.4 | Vigilant | 2026-04-19 | PRES-1 WiFi presence fully wired into status.json intelligence pipeline. Patio+Driveway cameras confirmed charging. Stale entities cleaned. |
| v4.0.3 | Vigilant | 2026-04-19 | PRES-1: sensor.arash_ssid re-enabled, device_tracker.arash_wifi replaced with binary_sensor.arash_wifi_home (template device_tracker not supported). BUG-MAINT-1 closed — avahi removal resolved HA mDNS conflict. Release/dev-render/linter scripts patched for id-only backlog items. |
| v4.0.2 | Vigilant | 2026-04-19 | Backlog sweep: Bold lock battery in HomeKit (template sensors Low→15%/Normal→75%/High→100%), HK-1/HA-14/HA-15 closed (done since v3.98.0), night automation verified active. |
| v4.0.1 | Vigilant | 2026-04-18 | Performance hardening: CPU governor powersave→performance (800MHz→2500MHz), nginx 4→2 workers + gzip for JSON/CSS/JS, journal 325MB→172MB, matter-server image removed (431MB freed), avahi/udisks2/e2scrub_reap masked, OP exim4+man-db removed. |
| v4.0.0 | Vigilant | 2026-04-18 | Watchdog startup grace period fixed — containers get 5min warmup window before watchdog fires. Fixes two broken grace blocks (heredoc quoting bug). Eliminates Grafana false-positive unhealthy alerts on restart. |
| v3.99.0 | Lean | 2026-04-18 | HP performance audit: InfluxDB 256MB→512MB (was at 97%), matter-server removed (freed 145MB), Homebridge retained at low priority (Nice=10, 150MB cap). Docker live-restore enabled. IPP polling disabled. watchdog matter-server removed. HA systemd Nice=-5. |
| v3.98.0 | Locks | 2026-04-18 | HK-1: 3 separate Bold lock accessory bridges (21075/76/77), converted from bridge mode. HA-14: oidc_provider removed. HA-15: go2rtc disabled. YAML homekit duplicate-key bug fixed — was silently dropping Living Room TV + 2 locks. |
| v3.97.0 | Expert | 2026-04-18 | Expert HA audit: Living Room TV to HA HomeKit (21074). Bold Smart Locks HACS + HA OAuth, Greenacres Locks bridge (21075). Work zone removed. Recorder duplicate merged. Matter/Thread/Wemo/dlna disabled. Lock area assignments. Bold Connect gateway hidden. Battery watchdog initial_state:true. |
| v3.96.0 | Forensic | 2026-04-18 | HA forensic audit pass 1: F1-F8. Daily HA backup rsync to OP (greenacres-ha-backup-sync.timer 04:30). Energy Dashboard. Girls TV remote hidden. Claude Usage reloaded. Weekday morning automation disabled (initial_state:false). |
| v3.95.0 | Audit | 2026-04-18 | HA audit infrastructure: rollback backup created, linter baseline confirmed 11/11, audit plan executed across HomeKit, automations, integrations, entity registry, recorder, and backup pipeline. |
| v3.93.0 | Clean | 2026-04-17 | LG ThinQ: 12 raw entities hidden from HA UI. HAP bridge RemainingDuration upgraded to real-time ISO timestamp countdown. Ghost homekit entry 21071 removed. Dead Orange Pi switch hidden. PSN token refreshed. |
| v3.92.0 | Intel | 2026-04-17 | Laundry done push notifications: greenacres-laundry-notify 2-min timer, deduplicates on LG event timestamp. Pattern engine: temperature baselines from InfluxDB (4 rooms, 96 hourly data points). |
| v3.91.0 | Laundry HAP | 2026-04-17 | HAP-python bridge (port 21072): Washer + Dryer each as single unified HomeKit accessory with 3 services (Valve + Motion + Humidity %). Replaced HA homekit bridge + Homebridge LG ThinQ plugin. systemd service greenacres-laundry-hap. PIN 469-78-126. |
| v3.90.0 | Sprint | 2026-04-17 | Intelligence quality sprint: P3 insights (printer ink, lock battery) auto-snoozed 24h after first daily fire. Pattern engine upgraded from events.jsonl to InfluxDB direct query — 10 rooms × 8267 motion events (was 1 room). Backlog cleanup: SSO duplicate removed, all 109 items assigned proper IDs (SEC/NET/HA/INT/UX/DEV/etc). |
| v3.89.0 | Brief | 2026-04-17 | Daily email prompt enriched: occupancy state/duration, weather, battery device status, LEARN-1 learning progress now sent to Haiku. NET-1 (Starlink WAN2, 2026-04-25), NET-2 (VLAN segmentation), NET-3 (UPS) added to backlog. Session discipline strategy locked in memory. |
| v3.88.0 | Quiet | 2026-04-17 | Intelligence noise reduction: battery-low suppressed when device is charging (patio 29%/driveway 24% both charging); fence+buddy camera offline alerts suppressed (intentionally offline — hardware not installed). influx_write now preserves intel fields if <10min old — fixes 4/5min data wipe cycle. Insight count 6→2 genuine signals. Alert fatigue score was 100/100 from 538 events/14d. |
| v3.87.0 | Signal | 2026-04-17 | Bug fix: intelligence engine indentation error trapped intel_meta and file write inside learned_preferences except block. On successful pattern_cache reads, status.json was only getting base keys — occupancy, weather, battery_health, vision, learned_preferences all missing. Fix: dedent intel_meta to correct scope. All 17 status.json keys now populate every 5-min cycle. Occupancy hero tile now live (Away / high confidence). |
| v3.86.0 | Wired | 2026-04-17 | LEARN-1 wired into status.json (pattern_cache.json → learned_preferences block) and admin page Scene Learning tile. Homebridge npm rebuild added to maintain-all (fixes native ABI mismatch after bundled Node.js upgrades). HA-7/OCC-1 deprioritised to phase2. |
| v3.85.0 | Dashboard | 2026-04-17 | Status page redesigned: hero strip (4 live tiles), compact server metrics table, active insights panel, camera status list, battery progress bars. New render functions wired to live data. Deployed via Python transformation on live source. |
| v3.84.0 | Flywheel | 2026-04-17 | LEARN-1: behaviour learning data flywheel live. HA automation logs every scene activation to events.jsonl. Pattern engine analyses by room/2h slot — outputs learned_preferences to pattern_cache.json. 70%/14d threshold marks a preference as recommended. BUG-MAINT-1: Wemo disabled (auto-discovered, wrong subnet). SSH errors were harmless dpkg output. |
| v3.83.0 | Wrap | 2026-04-17 | Dense tables: auto-width removes blank space, content-fit sizing. Text wrapping: overflow-wrap+word-break on all td — long values wrap, no layout blowout. Tighter cell padding (10px/8px). Removed white-space:nowrap on ref col — label badges now wrap freely. |
| v3.82.0 | Dense | 2026-04-17 | Table density: .t width:100% changed to auto so tables size to content not card width. Short tables compact, no blank space. Wide tables still fill container. max-width:100% + card overflow-x:auto handle overflow cases. |
| v3.81.0 | Width | 2026-04-17 | P1 ROOT CAUSE FIX: .page-content had no explicit width. In a flex column container, margin:0 auto prevents align-self:stretch — element sizes intrinsically. Tables with width:100% inside resolve to auto (unbounded), blowing past max-width:900px and hitting body overflow-x:hidden. Fix: .page-content{width:100%} globally + all per-page styles. Tables now have a defined 900px containing block to constrain against. |
| v3.80.0 | Clear | 2026-04-17 | P1 HOTFIX: Complete overflow audit — found 3 more pages with bare overflow:hidden (releases, ai-releases, phys-card). All 7 affected elements fixed. SW rewritten: versioned assets (style.css?v=X) now always fetched from network — stale-while-revalidate can never serve old CSS after a deploy. v3.80 SW activates immediately on next load. |
| v3.79.0 | Clip | 2026-04-17 | P1 HOTFIX: All platform pages clipping content on right edge. Root cause: per-page style blocks re-declared .card{overflow:hidden} overriding global fix. Fix: overflow-x:auto!important in style.css base .card rule (beats all per-page overrides permanently) + word-break:break-word on .t td + 4 affected pages fixed in-page (dev/docs/ai/dev-history) + SW cache v3.79. |
| v3.78.0 | Tiers | 2026-04-17 | NOTIF-1: 4-tier notification hierarchy. P1=immediate critical push (active security breach: doorbell+empty, night motion, coverage gap). P2=daily digest (battery/camera/credits — was incorrectly firing 3am critical pushes). P3=morning brief (warn). P4=on-demand (info). tier field on every insight in status.json. |
| v3.77.0 | Viewport | 2026-04-17 | UX-2: Global responsive self-heal. html overflow-x:clip at root (self-healing, all pages, industry standard). .card overflow-x:auto for table containment. .t max-width:100%. SW cache bumped to v3.77. Fixes horizontal scroll permanently. |
| v3.76.0 | Morning | 2026-04-17 | HA-11: Weekday morning thermostat routine. 07:00 Mon-Fri, 21C setpoint. Initial_state:true — approved, not launch-gated. automations.yaml updated. |
| v3.75.0 | Shadow | 2026-04-17 | AL-1: Adaptive Lighting shadow mode enabled. switch.greenacres_adaptive_lighting_greenacres ON. take_over_control:True. Observing for 7 days before active adjustment. |
| v3.74.0 | Hue | 2026-04-17 | HUE-1: Hue Bridge motion automations disabled via v2 API behavior_instances. 4 motion/presence instances disabled (hallway, landing, grass sensor, mimic presence). 17 physical switch/dimmer instances untouched. HA is sole automation controller. |
| v3.73.0 | Circuit | 2026-04-17 | CIRC-1: Claude API daily escalation hard cap. daily_escalation_count() reads hai_history.jsonl before writing escalation flag (cap: 3 anomaly_escalation/day). Same guard in greenacres-hai. Fixes 70-call flood from missing _last_escalation_at persistence. |
| v3.72.0 | Responsive | 2026-04-16 | UX-2: Full responsive design audit across all 13+ portal pages. Root cause: .card{overflow:hidden} in per-page inline styles overriding style.css cascade. Fix: overflow-x:auto !important at @media(max-width:1024px) + per-page rules in dev/docs/ai/admin. .page-content class added (28px→16px padding on mobile). SW cache bumped v3.42→v3.72. |
| v3.71.0 | Thornfield | 2026-04-16 | DASH: Command Centre Home view redesigned (smart greeting, presence chips, doorbell top-of-fold, 3-col rooms). Batteries view: replacement banner. Admin: Vision/Cache tiles fixed. Nightly pattern engine live (greenacres-pattern-engine, 02:00 timer) — 501 events processed, pattern_cache.json written. |
| v3.70.0 | Thornfield | 2026-04-16 | HA-3: Adaptive Lighting v1.30.1 installed (10 room groups, 2200-5500K, 10-100%, take_over_control). Main switch OFF (launch-gated). Visible in Lights view dashboard. |
| v3.69.0 | Thornfield | 2026-04-16 | INT-1: Claude API usage analytics tile in /admin/. GET /claude/usage endpoint in admin-api. Shows today calls, 7-day tokens, cost estimate. |
| v3.68.0 | Thornfield | 2026-04-16 | NOTIFY: Launch-gated policy formalised. All Claude-consuming timers disabled (morning/evening/escalation/camera-vision/morning-push). Single daily email at 12:00 (greenacres-daily-email, Mailjet, 1 Haiku call/day, template fallback). |
| v3.67.0 | Thornfield | 2026-04-16 | BUG: Escalation flood root cause fixed. Flag deletion + 5-min re-write was generating 169 API calls/day. Fix: _last_escalation_at in state_durations.json, 2h cooldown. Reduced from 2029 calls in 12 days to max 12/day. |
| v3.66.0 | Thornfield | 2026-04-16 | DOC-7: Onboarding guide fully updated — session cookie auth, 6 new key files, 4 new landmines, 9-step checklist, 11/11 linter references. /docs/onboarding/ reflects current platform state. |
| v3.65.0 | Thornfield | 2026-04-16 | DOC-4+DOC-6: Admin API reference (17 sections, 11 endpoints with method badges) and Recovery Runbooks (18 sections, 11 scenarios). /docs/ history table backfilled v3.59–v3.64. |
| v3.64.0 | Thornfield | 2026-04-16 | API-5: Files API knowledge base wired into Ask HAI. Four documents (platform architecture, device reference, automation policy, troubleshooting) injected per conversation via Anthropic Files API. load_file_ids() reads /var/lib/greenacres/files_api.json. files-api-2025-04-14 beta header alongside prompt caching. |
| v3.63.0 | Thornfield | 2026-04-14 | NAV-1: Cmd+K global search overlay on all 17 portal pages — indexes pages, features, actions, changelog items. GOV-2: changelog.json (75 items, 29 versions). HA-6: Guest dashboard (ui-guest.yaml, 3 views: Home/Lights/Environment). |
| v3.62.0 | Thornfield | 2026-04-14 | API-3: Batch API on weekly suggestion scripts (greenacres-backlog-suggest, greenacres-automation-suggest). 50% token discount + prompt caching = ~75% total cost reduction on weekly AI analysis. |
| v3.61.0 | Thornfield | 2026-04-14 | API-4/API-2: greenacres-camera-vision timer (5-min). Haiku vision AI analyses doorbell/driveway/garage1 snapshots — detects people, packages, vehicles. Alert insights injected into intelligence engine. Vision + Cache Savings tiles in /admin/. |
| v3.60.0 | Thornfield | 2026-04-14 | API-1: Prompt caching on all 4 Claude scripts (HAI briefings, Ask HAI, backlog-suggest, automation-suggest). cache_control: ephemeral on system prompt. 70-80% token cost reduction. HAI timers re-enabled. |
| v3.59.0 | Thornfield | 2026-04-14 | GOV: Sunrise/sunset routines disabled. All HA device automations set to initial_state: false. 13 ON (safety/security only: lock watchdog, away mode, doorbell, alarms, battery). Nothing live until agreed launch. |
| v3.58.0 | Thornfield | 2026-04-14 | SOV: Disabled all scheduled Claude API timers (hai-morning, hai-evening, morning-push, automation-suggest). Zero background API spend. Ask HAI remains on-demand only. |
| v3.57.0 | Thornfield | 2026-04-14 | HA-8: Three scenes added (Movie Mode / Morning Mode / Evening Mode). scenes.yaml wired via configuration.yaml. Callable from dashboard or automations. |
| v3.56.0 | Thornfield | 2026-04-14 | Dev backlog accuracy pass: backlog.json cleaned, 63 items correctly marked shipped (was stuck at v3.37.0). Dev page now accurate: 0 immediate, 21 near-term, 67 shipped. |
| v3.55.0 | Thornfield | 2026-04-14 | Met.no weather integration: weather.forecast_greenacres live via HA config flow. Weather chip on Home view, forecast card + 24h history graphs in Environment view. HA-13 shipped. |
| v3.54.0 | Thornfield | 2026-04-14 | HA history graphs in Environment view (24h: room temps/humidity/CO). Non-agreed automations set to OFF. Battery replacement logged for 2026-04-21. 5 new backlog items (HA-13–17). 18/18 world-class audit pass. |
| v3.53.0 | Thornfield | 2026-04-14 | HA live: enabled printer ink alert, guest_mode automations. Town Centre zone corrected to Southampton (50.9025, -1.4042). Work zone flagged for real address. |
| v3.52.0 | Thornfield | 2026-04-14 | HA world-class completion: area temperature/humidity assigned (5 areas live). input_boolean.guest_mode + input_select.home_mode helpers. Work/Town zones. WoL buttons in Media view. Home Mode chip on dashboard. 8 new backlog items (HA-6–12, V-EXT-2). |
| v3.51.0 | Thornfield | 2026-04-14 | HA polish: renamed 17 doubled entity names (cameras/thermostat/motion sensors). Device area assignments. 7 prepared disabled automations (weekday morning, night mode, bedtime check, guest mode, printer ink, frost protection). |
| v3.49.0 | Thornfield | 2026-04-14 | HA optimisation: Environment view (room temps/humidity/lux/CO ppm/sun). 5 new automations: illuminance-triggered lights (hallway/landing/office), sunrise heating, sunset notify, dimmer battery watchdog. Claude Credits + lock operator on dashboard. |
| v3.48.0 | Thornfield | 2026-04-14 | Dashboard audit: fixed person entity, kitchen smoke/CO, corrected motion sensors, person_detected on all cameras, PS5 media-player-card, 3 missing battery sensors, new Maintenance view (printer ink + 5 updates). 6 views total. |
| v3.45.0 | Thornfield | 2026-04-14 | Internet access: Tailscale Funnel + global auth. All pages on Tailscale block now require login (302→/login). LAN block unchanged. Linter + QA gate switched to LAN IP (192.168.0.10). Unblocks SSO-1. |
| v3.44.0 | Thornfield | 2026-04-14 | HA quick wins: recorder extended 7→30 days (base.yaml). Mushroom Cards dashboard deployed to HA config (5 views: Home, Security, Lights, Media, Batteries). HA-2/3/4 added to near-term backlog. |
| v3.43.0 | Thornfield | 2026-04-14 | Dev page: hide Todo/Immediate/Suggestions sections when empty. Compact note for patch releases. SUGGEST-7/8/10 formally recorded as shipped. |
| v3.42.8 | Thornfield | 2026-04-14 | Backlog housekeeping: SELF-1 and SELF-2 marked shipped in backlog.json |
| v3.42.7 | Thornfield | 2026-04-14 | Docs accuracy: greenacres-auth added to services table; weather_cache.json / proposed_fixes.jsonl / sessions.json added to file reference; TWIN-1 weather detector documented; TWIN-1 marked shipped in backlog.json |
| v3.42.6 | Thornfield | 2026-04-14 | JS lint gate in greenacres-release QA (node --check); Known Failure Modes landmines 13+14; /ai/releases/ hero v3.8.0 |
| v3.42.5 | Thornfield | 2026-04-14 | Docs history complete v3.42.1-v3.42.4; debug error display removed from loadHealth catch |
| v3.42.4 | Thornfield | 2026-04-14 | Admin page JS syntax fix — two broken onclick quote clashes crashed entire script block; all tiles stuck at Loading. Fixed Proposed Fixes buttons + UAT7 overlay dismiss. |
| v3.42.3 | Thornfield | 2026-04-14 | Service worker bypass for /admin/ and /dev/ — auth-protected pages never cached, always served fresh from disk. |
| v3.42.2 | Thornfield | 2026-04-14 | SW cache version bumped v3.14→v3.42, error visibility added to loadHealth catch block for diagnosis. |
| v3.42.1 | Thornfield | 2026-04-13 | Admin page fix: /status.json path corrected to /intranet/status.json (was 404 on Tailscale block). |
| v3.42.0 | Thornfield | 2026-04-13 | TWIN-1: Open-Meteo weather integration + storm-aware camera management — 12h forecast, storm alerts, weather block in status.json |
| v3.41.1 | Thornfield | 2026-04-13 | Login fix: POST path bug resolved (nginx strips /auth prefix), PAM authentication for Linux system users (arash), python3-pam installed |
| v3.41.0 | Thornfield | 2026-04-13 | Session cookie auth — greenacres-auth service replaces Basic Auth. /login page, 30-day cookie, rate limiting, internet-ready |
| v3.40.0 | Thornfield | 2026-04-13 | SELF-2: Self-healing approve panel + governed execution — two-step approve/execute with strict action whitelist |
| v3.39.0 | Thornfield | 2026-04-13 | SELF-1: proposed_fixes.jsonl pipeline — intelligence engine queues fixes, admin API approve/reject governance |
| v3.38.0 | Thornfield | 2026-04-13 | SOV-1/2: Claude credit routing + admin gauge |
| v3.37.4 | Thornfield | 2026-04-13 | Auto-reload: version.json + data-platform-version on all pages, bump_version_json() in release script |
| v3.37.3 | Thornfield | 2026-04-13 | Admin page fix: renderContainers() onclick JS crash (adjacent string literals), all tiles restored |
| v3.37.2 | Thornfield | 2026-04-13 | Global stale-data fix: d.ts to d.generated across all 12 portal pages |
| v3.37.1 | Thornfield | 2026-04-13 | Portal data fix: UAT1 stale-data timer, HAI headline live, nginx /intranet/ added to LAN server block |
| v3.37.0 | Thornfield | 2026-04-13 | Doc Excellence Batch 2: scroll-tracked ToC on /docs/ and /ai/ (DOC-3); lifecycle badges on release history tables via JS (NAV-2); Known Failure Modes section in /docs/ with 5 landmines documented (DOC-5); footer AI-agent version linter check added — 11/11 (GOV-1); effort/impact matrix on dev page (GOV-3); type badge and anatomy bar now baked into release template and persist across all future releases (DOC-1/DOC-2 fix). nginx: /intranet/ path added to LAN server block — fixes live data loading on 192.168.0.10. |
| v3.36.0 | Standard | 2026-04-13 | Doc Excellence Batch 1: BUG-1–5 footer version drift fixed across all pages; DOC-1 type badge on hero release card; DOC-2 rollback/severity/breaking changes anatomy bar; NAV-3 section last-updated tags on 27 sections across /docs/, /ai/, /releases/; GOV-4 release template (type/severity/rollback/breaking) added to workflow. |
| v3.35.0 | Occupancy | 2026-04-13 | SUGGEST-9: Visitor/occupancy context. compute_occupancy_context() from geofence + motion sensors. Confidence-rated (high/medium/low) with evidence list. Enriches doorbell_nobody_home, night_motion_nobody_home, security_coverage_gap insights with occupancy data. Status page occupancy card. occupancy block in status.json. |
| v3.34.0 | Forecast | 2026-04-13 | SUGGEST-6: Battery health predictor. compute_battery_health() unified drain-rate model via linear regression. Covers patio camera, driveway camera, front door lock. Warns 14d before critical, alerts at 3d. Battery Health table on /status/ with predicted replacement dates. battery_health block in status.json. |
| v3.33.0 | Verbose | 2026-04-13 | DEV15: Structured logging. Python logging module in greenacres-intelligence and greenacres-admin-api. Always DEBUG to stderr/journald. Per-detector counts, run summary (insights/alerts/warns/snoozed/elapsed). Named exceptions replace bare except:pass. journald retention: 30d max, 500MB cap, compressed. |
| v3.32.0 | Quiet | 2026-04-13 | SUGGEST-10: Alert deduplication and noise management. 6h dedup window replaces 4h. Per-alert snooze (4h/24h/7d) via admin-api POST /snooze. Alert fatigue scoring: 0-100 score, top 10 noise sources from 14d events.jsonl. Alert Fatigue section on /admin/ with inline snooze controls. |
| v3.31.0 | Notified | 2026-04-12 | V-M2: VAPID web push. VAPID key pair in /etc/greenacres-vapid.conf. greenacres-push script sends to all subscribers. Admin-api: /push/subscribe, /push/unsubscribe, /push/status. SW push+notificationclick handlers. /admin/ subscribe UI. Intelligence fires web push alongside HA push for new escalation alerts. |
| v3.30.0 | Adaptive | 2026-04-12 | V-A6: greenacres-automation-suggest analyses 7-day event patterns via Claude Haiku, proposes specific HA automations (trigger/action/priority/effort). Weekly timer Sun 07:00. Displayed on /admin/ automation suggestions panel. nginx: automation_suggestions.json served from both server blocks. |
| v3.29.0 | Clear | 2026-04-12 | /dev/ restructured as pure action surface. ADRs, Rejected Alternatives, and Incident Log moved to /docs/ sections 13/14/15. /docs/ TOC updated. /dev/ shows only: physical actions, AI suggestions, backlog (3 tiers), chart picker, recently shipped, completeness, reference link. |
| v3.28.0 | Proactive | 2026-04-12 | QW28: Patio camera battery trend (21-day threshold). QW29: Visitor insights enriched with house-empty duration + camera coverage. QW30: Event dedup 1h→4h. V-A7: Camera auto-recovery via HA reload_config_entry (30-90 min transient, 4h cooldown). Dev cleanup: credits action removed, fence/buddy deadline set, SUGGEST-8 rejected. |
| v3.27.0 | Mapped | 2026-04-12 | V-D6: Live SVG network topology on /status/ — 3-tier hierarchy (gateway → switches → APs) with per-node CPU/mem/status from status.json in real time. |
| v3.26.0 | Insightful | 2026-04-12 | V-D5: Quick Chart Picker on /dev/ (16 history series, dropdown+canvas, 30-day trends). V-A6 admin panel: Top AI Suggestion card on /admin/ fetches /suggested_items.json, shows top suggestion with confidence badge. |
| v3.25.0 | Alert | 2026-04-12 | QW24: intel_meta card on /status/ (detector run time, events logged). QW25: HAI briefing card on /status/ via Promise.all. QW26: Security coverage gap detector (alerts when 2+ cameras offline while unoccupied). QW27: Starling camera battery intelligence detector. |
| v3.24.0 | Informed | 2026-04-12 | QW23: Lock battery level chart on /analytics/ — 30-day trend from history.json lock_battery series with 20% threshold line. |
| v3.23.0 | Resilient | 2026-04-12 | QW20: Camera online summary card (N/7, offline named). QW21: Doorbell ring + package delivery card (when active). QW22: Intelligence HA restart detector (insight when HA up <2h). Status page fully reconstructed after corruption incident. |
| v3.22.0 | Clear | 2026-04-12 | QW16: Analytics OP layout fixed + OP Memory % chart added. QW17: Nest Protect stat card (clear/alarm + battery). QW18: Thermostat cards now show humidity (from Starling). QW19: Today (1-day) filter button added to /events/. |
| v3.21.0 | Sharp | 2026-04-12 | QW13: Health scores (security/comfort/infra) as stat cards on /status/. QW14: Network health card (N/N devices online, gateway CPU). QW15: Active binary sensor cards (occupancy, door, motion) on /status/. |
| v3.20.0 | Vigilant | 2026-04-12 | Critical fix: V-A3 watchdog HP_SERVICES corrected (was monitoring oneshot/non-existent services, causing HA notification spam). HA push payload updated to modern iOS format. QW9: CO and low-battery sensor alerts on /status/. QW10: Credits insight shows remaining units. QW11: Event filter count badges. QW12: OP Pi-hole stats in Pi-hole card. |
| v3.19.0 | Aware | 2026-04-12 | QW5: presence card on /status/ (who is home). QW6: Pi-hole live stats (% blocked, queries, clients). QW7: force-refresh button. QW8: active media shown when on. |
| v3.18.0 | Polished | 2026-04-12 | QW1: active alert count in browser tab title on all 13 pages (e.g. (2) Greenacres Status). QW2: /status/ live thermostat current+target temps. QW3: /status/ lock state, battery %, and HP uptime. QW4: /docs/onboarding/ landmines and session checklist updated for v3.17.0 state. |
| v3.17.0 | Autonomous | 2026-04-12 | V-A3: Pre-authorised auto-restart whitelist. greenacres-watchdog monitors 12 services: all Docker containers + HP systemd services (greenacres-intelligence, greenacres-admin-api, greenacres-sse-server, nginx) + OP services. Auto-restart events logged to events.jsonl. /admin/ shows full whitelist. |
| v3.16.0 | Monitored | 2026-04-12 | V-C2: WAN bandwidth chart on /analytics/ — download and upload Mbps from enp1s0. greenacres_influx_write computes live rate via delta state file. greenacres_history_write adds 30-day hourly series via InfluxDB derivative(). Chart renders once data accumulates. |
| v3.15.0 | Offline | 2026-04-12 | V-M3: PWA offline mode. Replaced cleanup stub with a real caching service worker. Cache-first strategy for all 13 pages and static assets; network-first for live JSON data (status.json, history.json, hai_briefing.json, events.jsonl); HA API and admin endpoints bypass cache entirely. Hub installs as a standalone app and loads from cache when offline. |
| v3.14.0 | Secured | 2026-04-12 | SEC11: Basic Auth on /dev/ and /dev/history/ (same credentials as /admin/). Backlog and dev planning page are now credential-gated. /dev/backlog.json remains publicly readable for internal tooling. Linter and QA gate updated to accept 401 on protected paths. |
| v3.13.0 | Refined | 2026-04-12 | SE2: generic card renderer on /controls/ — auto-renders HA entity types (media_player with on/off toggle) from status.json. UAT6: event deduplication on /events/ — identical events grouped with ×N recurrence badge and span duration. |
| v3.12.0 | Connected | 2026-04-11 | SEC8: CSRF protection on admin-api (X-Requested-With). DEV6: auto version tag derivation. AG4: Pi-hole top queried domains chart on /analytics/ (Pi-hole v6 API). UAT3: ARIA labels, role=main, aria-live across all 13 pages. |
| v3.11.0 | Fortified | 2026-04-11 | DEV11: /docs/onboarding/ agent brief page (cold-start reference). SEC7: rate limiting on /admin-api/ (4r/m burst=8). SEC9: X-Frame-Options, X-Content-Type-Options, HSTS, Referrer-Policy, Permissions-Policy. UAT7: connection-lost overlay after 3 consecutive failures. |
| v3.10.0 | Remote | 2026-04-11 | V-P1+SEC10: Tailscale VPN installed on HP. Valid TLS cert (hp.tailabbaf3.ts.net, 90-day auto-renew via greenacres-renew-cert). Hub accessible from anywhere via HTTPS. No port forwarding, no public exposure. |
| v3.9.0 | Resilient | 2026-04-11 | UAT1: amber stale-data banner on all 13 pages when status.json >6min old. UAT2: bottom degradation bar when HAI on template-engine fallback. DEV14: last-refreshed timestamp on urgency block in /dev/. |
| v3.8.0 | Hardened | 2026-04-11 | SEC3-6: Basic Auth on /admin/+/admin-api/+/filebrowser/, XSS escapeHtml() in /events/, ha-filebrowser loopback-only, Mosquitto auth enforced. DEV4: greenacres-linter (10-check weekly cron). DEV5: release events in events.jsonl. DEV8: docs cross-references. DEV9: capability matrix updates. DEV10: backlog completeness score on /dev/. |
| v3.7.0 | Suggestions | 2026-04-11 | DEV12: AI-powered proactive backlog generation. greenacres-backlog-suggest analyses 14d events.jsonl weekly, calls Claude Haiku, writes suggested_items.json. AI-Suggested Items section on /dev/ with evidence-backed suggestions. |
| v3.6.0 | Intelligence | 2026-04-11 | V-A5: HAI upgraded from template engine to claude-haiku-4-5-20251001. Contextual briefings from live system state. Template fallback preserved. New API key (GA) installed. |
| v3.5.0 | Pipeline | 2026-04-11 | DEV2+DEV3+DEV7: backlog.json canonical source, release preview+confirm, 18-check QA gate. greenacres-dev-render installed. /dev/backlog.json nginx alias. |
| v3.4.0 | Blueprint | 2026-04-11 | DEV1: Complete /dev/ rebuild with structured backlog tiers, Physical Actions, ADRs, Why Not Register, Incident Log. /dev/history/ archive. greenacres-release glob depth + mark_dev_shipped fixes. |
| v3.3.2 | Control | 2026-04-11 | SEC1+SEC2: HA JWT moved to /etc/greenacres-secrets.conf (600 root:root). greenacres-admin-api runs as greenacres-admin user with docker group membership only. |
| v2.2.0 | Design | 2026-04-10 | Design system v2.1 — full CSS overhaul. 5-level surfaces, global .page-hero, heading scale, custom scrollbars, :focus-visible, shadow system, badge system, responsive pass at 480/600/768/960px. Benchmarked against Linear, Vercel, Raycast. Design programme (UX1–UX5) added to /dev/. |
| v2.1.0 | Ask | 2026-04-10 | Ask HAI page deployed at /help/. greenacres-ask-cto backend service on :8766, nginx proxy at /ask-cto. Full chat UI with suggestion chips, typing indicator, graceful offline state. Ready to go live on API credit top-up. |
| v2.0.0 | Craig | 2026-04-10 | greenacres-release automation script deployed. One command updates version badges on all pages, adds release cards to /releases/ and /ai/releases/, updates /dev/ last-deploy note. Craig principle adopted: platform documents itself on every push. |
| v1.9.0 | Sync | 2026-04-09 | Data accuracy fixes (lock state, Pi-hole blocked count, network device count). Platform Docs (/docs/), AI Agent (/ai/), Dev (/dev/) pages launched. 10-item nav. All pages v1.9.0. |
| v1.8.0 | Hub | 2026-04-08 | Full intranet hub at https://192.168.0.10. Controls, Analytics, Status, Admin, Releases pages. Self-hosted fonts. HA API proxy. HAI briefing on hub home. Intelligence scoring fixed (comfort 35→100). Apple-style Release Center. |
| v1.7.0 | Starling | 2026-04-07 | Starling Hub fully integrated into status.json — cameras, thermostats, Protect live. CTO Capability Report generated. Intranet audit passed. History chart gradient fix. Data export button. |
| v1.6.0 | Vision | 2026-04-07 | Lighthouse 100/100/100. About page at /about/. Pi-hole v6 API confirmed. Both Pi-holes v6.5, adlists identical. |
| v1.5.0 | Roaming | 2026-04-05 | Full infrastructure hardening sprint: SSH fixed (Mac→HP/OP), fail2ban whitelists, /dev/null OP permission, Omada NTP+airtime fairness+band steering, Wi-Fi channels optimised, LandingAP TX power reduced. HA: Starling battery crash fixed (88→4 unavailable entities), IP ban cleared, SmartThings removed, Bluetooth cap_add, weekly HA backup, area assignments. PWA service worker, container queries, ARIA, pull-to-refresh, sparklines, haptics. SSE service deployed. |
| v1.4.0 | Intelligence | 2026-04-05 | HAI Phase 8a (intelligence engine: anomaly detection, z-score baselines, state durations, cross-stream correlations) + Phase 8b (briefing layer: 07:00/19:00/alert, template engine as zero-cost fallback). Health score rings, active insights, HAI briefing card in portal. |
| v1.3.0 | Platform | 2026-04-04 | InfluxDB + Grafana deployed. 11 measurements, 3 dashboards. Portal with SSE real-time push. History tab (6-panel, 7-day). Monitoring portal deployed at :8080. |
| v1.2.0 | Harden | 2026-04-03 | Backup fixed (26MB, flock, 02:00). Watchdog extended to OP. Mailjet email alerts confirmed on both servers. |
| v1.1.0 | Connect | 2026-04-02 | Monitoring infrastructure. Omada integration. Backup strategy. InfluxDB initial setup. |
| v1.0.0 | Stabilise | 2026-04-01 | Initial platform stabilisation. Homebridge restart policy, unbound reload fix, swap duplicate removed, socket buffers, ghost timers removed. |
12. Platform Risks & Roadmap Updated: v4.0.34
| Risk | Severity | Mitigation |
|---|---|---|
| HP single point of failure — all writes, all state | High | Daily backup to /var/backups/greenacres/. Docker restart policies. Watchdog alerts. Gap: no offsite copy. |
| LAN-only access — no remote operations capability | Medium | None currently. All access requires home network presence. |
| OP disk capacity (small SD card) | Low | Manual monitoring. No automated alert at threshold. Current usage: low. |
| Single-engineer knowledge base | Low | Full documentation at /docs/ + /ai/. Memory system. Any engineer can onboard from current docs state. |
| Ref | Item | Horizon | Rationale |
|---|---|---|---|
| V-P1 | Tailscale VPN remote access | 3 months | Full remote operations. SSH, HA API, status.json accessible from any location. Zero open ports. |
| V-P2 | iOS push notifications (Pushover / ntfy) | 3 months | Sub-second push for lock state, service failures, HAI alerts. Replaces email-only alerting. |
| V-P3 | Offsite cloud backup (rclone + B2/S3 Glacier) | 3 months | Disaster recovery. Current backups are local-only. ~$0.005/GB/month at B2. |
| V-P4 | 30-day history retention | 3 months | Extend from 7-day to 30-day hourly. Monthly trend analytics. InfluxDB already stores indefinitely. |
| V-P5 | Predictive maintenance engine | 6 months | HAI forecasts battery/disk/camera degradation. Days-until-critical vs current threshold alerts. |
| V-P6 | OP promoted to active secondary | 6 months | Replicated read-only dashboard on OP. HP failure tolerance. Currently OP is DNS-only. |
13. Architecture Decision Records Updated: v4.0.34
Key decisions that shaped the platform — why things are the way they are. Prevents re-litigating settled questions.
| Decision | Context | Why chosen | Trade-off accepted | Date |
|---|---|---|---|---|
| Flat network (no VLANs) | Home network with Nest cameras, HomeKit devices, Hue, Matter | HomeKit mDNS requires flat Layer 2 for device discovery. VLANs break multicast across segments without complex mdns proxy config. | No network segmentation. Guest and IoT devices share LAN. Mitigated by device auth (SEC3+) and fail2ban. | Apr 2026 |
| /23 subnet (192.168.0.0/23) | DHCP reservation scheme needed for ~30 fixed devices | 512-host range. Reservations in .0.x block; dynamic pool in .1.x block. Clean visual separation. Load-bearing — do not change. | Larger-than-needed address space for a home network. Negligible practical cost. | Apr 2026 |
| InfluxDB over Prometheus | Selecting time-series database for monitoring stack | InfluxDB already in the homelab ecosystem. Line protocol is simple. Grafana datasource works out-of-box. Right tool for home automation scale. | Prometheus has richer ecosystem and pull-model is often cleaner. Accepted: polyglot stack overhead not justified at this scale. | Apr 2026 |
| Independent Pi-hole on each server | DNS redundancy across HP (.10) and OP (.20) | Decommissioned gravity-sync. Each Pi-hole runs independently with identical adlists. OP failure doesn’t break HP. No sync fragility. | Adlist updates must be applied to both. Mitigated by maintain-all running on both servers at 04:00. | Apr 2026 |
| status.json as single state aggregation | Architecture for live data delivery to hub pages | All consumers read one file. Writer runs every 60s. SSE server pushes on file change (~2s latency). Simple, no WebSocket complexity, works with static hosting. | 60s staleness window. Mitigated by SSE push layer reducing practical latency to ~2s. | Apr 2026 |
| Starling Hub as Nest bridge (not HA Nest integration) | Integrating Nest cameras, thermostats, and Protect into platform | Starling local API exposes richer fields: batteryStatus, packageDelivered, coLevel (numeric), hvacState (actually heating now vs mode). HA Nest integration is cloud-dependent and field-limited. | Additional device ($) and dependency. Battery/charging on StarlingHub itself to monitor. Accepted: field richness justifies it. | Apr 2026 |
| Sonnet default / Opus for deep reasoning only | Model selection for CTO mode operations | Sonnet handles all operational workloads (briefings, diagnosis, coding, deployments) at ~5x lower cost than Opus. Opus reserved for complex architectural decisions only. | Some nuanced reasoning tasks may benefit from Opus. Policy: default Sonnet, escalate explicitly. Validated 2026-04-08. | Apr 2026 |
14. Rejected Alternatives Updated: v4.0.34
Options explicitly evaluated and rejected, with rationale. Prevents the same conversation happening twice.
| Rejected | Why rejected | Date |
|---|---|---|
| VLANs / network segmentation | HomeKit mDNS breaks across VLANs without an mdns proxy. Flat network is load-bearing for device discovery. See ADR above. | Apr 2026 |
| gravity-sync for Pi-hole | Sync failures and version drift added fragility without benefit. Both Pi-holes now run independently with identical adlists via maintain-all. | Apr 2026 |
| Separate /backlog/ page | One planning surface is better than two. /backlog/ redirects to /dev/. Splitting planning creates a second place to look and maintain. | Apr 2026 |
| Docker on Orange Pi (.20) | OP is ARM-based with 512MB RAM. Native Pi-hole + Unbound is sufficient and stable. Docker overhead not justified for a secondary DNS server. | Apr 2026 |
| Root user for greenacres-admin-api | Privilege escalation risk. SEC2: service now runs as greenacres-admin user with docker group membership only. Shipped v3.3.2. | Apr 2026 |
| Bearer token in nginx config | Plaintext HA JWT visible in /etc/nginx config. SEC1: moved to /etc/greenacres-secrets.conf (chmod 600, root:root). Shipped v3.3.2. | Apr 2026 |
| Cloud dependency for core operations | Status, controls, briefings, and DNS all operate LAN-only. No cloud dependency for core platform function. HAI uses local template fallback when Claude API unavailable. | Apr 2026 |
| Prometheus for metrics | Polyglot stack overhead without benefit at home automation scale. InfluxDB already in stack and covers all time-series needs. See ADR. | Apr 2026 |
| Consumable inventory & supplier API integration (SUGGEST-8) | Battery trend prediction already shipped (QW28). Printer ink is a one-off. External supplier APIs add fragile cloud dependency for minimal value at home scale. | Apr 2026 |
15. Incident Log Updated: v4.0.34
Post-mortems for platform incidents. Root causes, fixes, and preventions.
| Date | Severity | What broke | Root cause | Fix & Prevention |
|---|---|---|---|---|
| 2026-04-05 ~6 days |
Medium | maintain-all silent skip Daily maintenance not running since Apr 5 |
/var/lock/system-maintenance.lock was owned by arash on tmpfs. Root couldn’t acquire lock. Script silently exited at startup. | maintain-all now detects and removes non-root-owned lock at startup. Tmpfs resets on reboot so this recurs without the fix. |
| 2026-04-06 ~hours |
Medium | HAI data race Health scores + insights disappearing from status.json |
influx writer (60s) was overwriting status.json entirely, erasing health/insights/intel_meta written by intelligence engine (5min). Race window = every 60s. | influx writer now preserves existing health, insights, and intel_meta keys from current status.json before writing. Merges rather than replaces. |
| 2026-04-06 ~2 hours |
High | Email storm — 130 emails HAI escalation firing every 5 minutes |
Temperature anomaly false positives (2 data points, std=0.18°C triggering 4σ alert). Escalation flag set every 5min. HAI handler fired every 5min. Email on each 401 failure. | 4h email rate limit per alert type. 30-min escalation flag refractory period. Anomaly detection: 48h baseline + 6 sample minimum (was 24h + 3). Email skipped when API key not set. |
| 2026-04-06 | Medium | Anomaly detection false positives Spurious temperature alerts with insufficient baseline |
MIN_BASELINE_RECORDS=24 and bucket min=3 allowed z-score calculation with too few data points. Tiny standard deviations caused 4σ triggers on normal variation. | MIN_BASELINE_RECORDS raised 24→48. Bucket minimum count raised 3→6 (per-bucket) and 2→4 (cross-bucket). Anomaly detection now robust against sparse baselines. |
| 2026-04-17 ~hours |
Medium | SELF-1 false fix proposals — matter-server Intelligence engine proposing docker restart matter-server every 5 min |
matter-server intentionally decommissioned but still in CONTAINERS list. SELF-1 saw it as down >5min, proposed restart every run. | Added DECOMMISSIONED exclusion set in intelligence engine. Removed matter-server from all tracking scripts (influx_write, collect_metrics). |
| 2026-04-18 ~1 session |
Medium | YAML duplicate template key Bold lock battery sensors silently missing from HA |
Two template: blocks in base.yaml. YAML silently drops the first block, so Bold lock battery sensors were never registered. |
Merged both template blocks into a single block. All template sensors (batteries + presence) now in one template: declaration. |
| 2026-04-19 ~1 session |
Low | Toolchain KeyError on id-only backlog items greenacres-release, dev-render, and linter crashed on newer backlog items |
Older backlog items used ref field; newer items (BUG-MAINT-1, cap_3, phys_1, phys_2) only had id field. All three scripts assumed ref existed. |
Fixed all three scripts with .get('ref', item.get('id', '?')) defensive pattern. |
16. Known Failure Modes & Resolution Updated: v4.0.34
Documented landmines — each with root cause, symptoms, and resolution. Update this section when a new failure mode is confirmed.
| Failure Mode | Root Cause | Symptoms | Resolution |
|---|---|---|---|
| Service worker caches auth-protected pages Landmine #13 |
SW uses cache-first for all pages not in BYPASS. Auth-protected pages (/admin/, /dev/) were not bypassed — SW served stale HTML with broken JS. JS syntax errors fail silently, crashing the entire script block. | All tiles show Loading permanently on both browsers. Hard refresh has no effect — SW intercepts it. | /admin/ and /dev/ are in SW BYPASS list (sw.js). Any new auth-protected page must be added to BYPASS. Validate JS with Node before release. |
| Single-quote clash in onclick JS strings Landmine #14 |
Building HTML strings with single-quote delimiters where onclick values also contain single quotes terminates the outer string early. Remaining text becomes unexpected identifiers — entire script block crashes. | All tiles stuck at Loading. Silent failure (empty catch block). Affects any page with string-concatenated HTML containing inline onclick handlers. | Use data attributes: data-action="approve" onclick="fn(this.dataset.id,this.dataset.action)". Or HTML entities for quotes. Always validate with Node.js syntax check before release. |
| status.json race — intelligence fields overwritten Landmine #12 |
The base status generator runs every 60s and writes status.json, overwriting the insights, health, battery_health, alert_fatigue, occupancy, and intel_meta blocks set by the intelligence engine. |
Running the intelligence engine and then immediately reading status.json shows no intelligence fields, or fields from the previous run. Status page shows “No insights” even when the engine just ran. | Always run the intelligence engine and read status.json in a single SSH command: sudo python3 /usr/local/sbin/greenacres-intelligence 2>/dev/null; sudo python3 -c "import json; d=json.load(open('/srv/www/intranet/status.json')); print(list(d.keys()))" |
| snooze.json write fails — file owned by greenacres-admin Landmine #10 |
/var/lib/greenacres/snooze.json is created and owned by the greenacres-admin service user. The intelligence engine runs as root but encounters a .tmp permission error when attempting an atomic rename-write. |
Intelligence engine raises PermissionError or OSError on snooze write. Snooze state is not persisted. Alert suppression stops working after a restart. |
Intelligence engine must write snooze.json using direct open(path, 'w') write — NOT atomic rename (os.rename) — to avoid creating a .tmp file in the same directory. Admin API also writes directly. If permission error recurs: sudo chown root:root /var/lib/greenacres/snooze.json && sudo chmod 644 /var/lib/greenacres/snooze.json |
| Camera recovery cooldown not persisted Landmine #11 |
detect_camera_recovery() writes cooldown timestamps to state_cache during the detector loop. The first save_state() call happens inside update_state_durations() — before the detector loop runs — so cooldown writes are not persisted to disk. |
Camera recovery attempts retry every 5 minutes instead of the intended 4-hour cooldown. HA reload_config_entry is called repeatedly on the same offline camera. |
The intelligence engine must call save_state(state_cache) TWICE per run: once inside update_state_durations() (for watch state), and once after the detector loop (for cooldown state). Both saves are required — removing either breaks one of the two use cases. |
| nginx new endpoint not responding on one interface Landmine #9 |
nginx has TWO server blocks on port 443: one for the Tailscale IP and one for the LAN IP. Adding a new location block to only one server block means the endpoint is accessible from one network interface but returns 404 on the other. |
New JSON endpoint works on Tailscale (https://hp.tailabbaf3.ts.net) but returns 404 on LAN (192.168.0.10), or vice versa. | Any new location block in nginx must be added to BOTH server blocks in /etc/nginx/sites-enabled/intranet-https.conf. After editing: sudo nginx -t && sudo systemctl reload nginx |
| re.sub with HTML content corrupts output Landmine #1 |
re.sub(pattern, replacement_string, html) interprets backslashes and capture group references (\1, \g<0>) in the replacement string. HTML content containing backslashes or ampersands can silently corrupt the output. |
HTML page renders incorrectly after a Python-based substitution. Backslash sequences are dropped or replaced. Subtle corruption that may not be immediately visible. | Always use a lambda for the replacement: pattern.subn(lambda m: replacement_string, html). The lambda prevents Python from interpreting the replacement as a regex substitution pattern. |
17. Admin API Reference Updated: v4.0.31
Internal REST APIs served by two greenacres Python daemons. All endpoints are LAN-only behind nginx and require session cookie auth. POST/DELETE endpoints additionally require X-Requested-With: GreenacresAdmin as CSRF protection.
| Endpoint | Method | Auth | Description & Response |
|---|---|---|---|
| Admin API — port 8767, served at /admin-api/ | |||
GET /docker/logs/{name} |
GET | Session cookie | Last 60 lines of Docker container logs. name must be in: homeassistant, grafana, influxdb, ha-filebrowser, matter-server, mosquitto. Returns {"name":str, "logs":str}. 403 if name not in allowlist. |
GET /autoreset/whitelist |
GET | Session cookie | Current container autoreset whitelist from /var/lib/greenacres/autoreset.json. Returns the full JSON object. |
GET /push/status |
GET | Session cookie | Web Push state. Returns {"vapid_public_key":str, "subscribers":int}. |
GET /snooze |
GET | Session cookie | Active alert snoozes. Returns {"snoozes":{id:{"until":epoch,"hours":int,"reason":str,"snoozed_at":epoch}}}. Expired snoozes are filtered out. |
GET /proposed-fixes |
GET | Session cookie | Self-healing proposed fixes queue. Returns {"fixes":[...]}. Each fix: id, trigger, proposed_action, status (pending/approved/applied/failed), created_at. |
POST /docker/restart/{name} |
POST | Cookie + CSRF | Restart a Docker container. Name must be in allowlist. Returns {"ok":bool,"message":str}. Timeout 45s. Event logged to events.jsonl. |
POST /push/subscribe |
POST | Cookie + CSRF | Register Web Push subscription. Body: {"endpoint":str,"keys":{"p256dh":str,"auth":str}}. Deduplicates by endpoint. Returns {"ok":true,"subscribers":int}. |
POST /push/unsubscribe |
POST | Cookie + CSRF | Remove Web Push subscription. Body: {"endpoint":str}. Returns {"ok":true,"subscribers":int}. |
POST /snooze |
POST | Cookie + CSRF | Snooze an insight alert. Body: {"id":str,"hours":4|24|168,"reason":str}. id must match [a-z0-9_]+. Returns {"ok":true,"until":epoch}. |
DELETE /snooze/{id} |
DEL | Cookie + CSRF | Clear a snooze immediately. Returns {"ok":true}. |
POST /proposed-fixes/{id}/execute |
POST | Cookie + CSRF | Execute an approved proposed fix. Fix must have status=approved. Whitelist: docker_restart, log_cleanup, service_restart. Returns {"ok":bool,"message":str}. Self-heal event logged. |
| Ask HAI API — port 8766, served at /help-api/ (internal alias: 127.0.0.1:8766) | |||
POST /ask |
POST | Session cookie | Single-question or multi-turn chat. Body v1: {"question":str}. Body v2: {"messages":[{"role":"user","content":str},...]}. Returns {"ok":bool,"text":str,"offline_mode":bool?}. Falls back to status.json if credits exhausted. Files API knowledge base injected per call. |
POST /briefings |
POST | Session cookie | Last 7 HAI briefing summaries from hai_history.jsonl. Returns {"ok":true,"briefings":[{"ts","time","type","model","headline","narrative","priorities","recommendation"}]}. |
All POST and DELETE requests to the Admin API must include the header X-Requested-With: GreenacresAdmin. Requests missing this header receive 403 {"error":"csrf check failed"}. GET endpoints do not require the header — only session cookie auth.
POST /{ID}/api/v2/login{"username":str,"password":str}. Returns: {"errorCode":0,"result":{"token":str,"omadacId":str}}. Token used as Csrf-Token header in subsequent requests.GET /api/info{"result":{"omadacId":str,"controllerVer":str,"apiVer":str}}. omadacId needed for subsequent API paths.GET /{CONTROLLER_ID}/api/v2/sites/{SITE_ID}/devices[{"name":str,"mac":str,"type":"ap"|"switch"|"gateway","status":int,"clientNum":int,"ip":str,"model":str},...]. HTTPCookieProcessor required for session persistence. 6 devices fetched: 3 APs (EAP653/EAP650), 1 gateway (ER7206), 2 switches (SG2210P).GET /{CONTROLLER_ID}/api/v2/sites{"result":{"data":[{"id":str,"name":str},...]}}. Used to discover site UUIDs. Greenacres site: 690af86fbef39c1cb66167ab.GET /{ID}/api/v2/sites/{SITE_ID}/clientshttp.cookiejar.CookieJar() + HTTPCookieProcessor for session persistence. Without proper cookie handling, consecutive requests fail with HTML response (auth failure). Deployed in /usr/local/sbin/greenacres_omada_mac_collector.py.