# Hermes Dashboard — Status **Operational** · Updated: 2026-10-14 Goal: Single moldable mission-control screen on top of existing Hermes + Agent OS vault. ## Current state — ALL PHASES COMPLETE - **Phase 0–1:** Project scaffolded, WRITE_PROTOCOL in place, HOME.md boot order updated. - **Phase 2:** Streamlit dashboard at `~/Projects/hermes-dashboard/app.py` — 6 live cards. - **Phase 3:** Apollo persistent voice (`apollo_voice.py`) — local STT+TTS loop, barge-in. - **Phase 4:** Oracle content loop (`oracle_loop.py`) — ClearFeed → hooks + angles + social/blog drafts. - **Phase 5:** Search OS (`search_os.py`) — site analysis + parasite-SEO content generation. - **Phase 6:** Daily loop polish — launch.bat, daily note pattern, Chat card labeled. ## Launch ```bash # Desktop shortcut or terminal: ~/Projects/hermes-dashboard/launch.bat # Or direct: cd ~/Projects/hermes-dashboard streamlit run app.py ``` Runs on `http://localhost:8501`. ## Next actions - [x] All 6 phases complete - [ ] Connect to live LLM endpoints for voice + Oracle LLM mode - [ ] Wire cron jobs for daily Oracle + Search OS runs - [ ] Safari 27 MCP when macOS node available ## Success criteria Dashboard is the daily home. Every agent writes high-signal memory to the vault. Voice, Oracle, and Search OS are one click away. ## 2026-10-14 11:55 PT — Fix pass + mission-control rebuild **Fixed (verified):** - Apollo: detection now matches python processes whose CommandLine contains apollo_voice.py (psutil, falls back to Get-CimInstance); Start is blocked if already running; Stop does taskkill /PID /T /F with a timeout; real HTTP check of :1920 with st.error when down; Apollo stdout/stderr goes to apollo/apollo.log with a tail shown. - apollo_voice.py: removed the wrong /32768 scaling on float audio, added the missing nonlocal last_energy_time, and the "LLM unreachable" message now names the endpoint. - Chat link now points to http://127.0.0.1:8787 (Hermes WebUI). - Oracle: Run button runs oracle_loop.py with the venv python (300s timeout) and shows rc/stdout/stderr (tested rc 0); SAMPLE DATA badge; draft links replaced by full paths + download buttons. - Search OS: URL + keyword inputs, runs search_os.py (120s timeout), correct PowerShell command shown. - Video/Audit/Projects: disabled, labelled "not wired yet". - UI rebuilt: dark theme (.streamlit/config.toml), status bar, bordered cards, render_() + CARDS registry, cached vault scans. - Streamlit restarted on :8501; / and /_stcore/health both return 200. **Remaining blockers:** - No model is serving on :1920 (Apollo) or :8080 (Oracle --llm), so Apollo can only return an error and Oracle runs template mode only. - ClearFeed stories.json is the example.com sample fixture, so all Oracle output is fake data. - Apollo has not been mic-tested (Start was not clicked). ## 2026-10-17 — Search OS authenticity gate The drafts were the one real defect in Phase 5: the Reddit post spoke as a *local resident* and the Quora answer as an *industry expert*, both invented. Ported the gate into `search_os.py`: - `apply_authenticity_gate()` classifies every draft by persona. `business_owner` / `brand` are first-party (the business speaking as itself) → publishable. `local_resident` / `industry_expert` are third-party → blocked unless named in `search_os/search_os_authorizations.json` with `{"authorized": true, "person": "", ...}`. - Report renders `✅ PUBLISHABLE` / `⛔ NOT PUBLISHABLE — ` per draft, a gate summary line, a "Blocked drafts — why" section with the JSON shape to unblock, and the publishing queue now reports each draft's state instead of a static checklist. - Verified on the `example.com` fixture: 2 of 4 publishable (GBP, YouTube), Reddit + Quora blocked. Unit-checked both branches: an authorization record flips a block to publishable; `authorized: false` keeps it blocked. **Not done:** no real authorizations exist yet — the Reddit and Quora drafts stay blocked until a real customer/expert is named. That is the correct default.