Files
lgtv/.claude/handoffs/2026-10-24-110715-hermes-findings-fixed.md
Mortdecai 5308dc2fd3 docs: handoff — hermes reviewer findings fixed
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 11:07:44 -04:00

6.1 KiB

Handoff: hermes reviewer findings — all 3 fixed and deployed

Session Metadata

  • Created: 2026-10-24 11:07:15
  • Project: /home/claude/bin/lgtv
  • Branch: master
  • Session duration: ~20 min

Recent Commits (for context)

  • cc0e023 fix: catch helper timeouts in run(); report probed state when a command fails
  • 2f96013 docs: handoff — pairing fix verified on/off/on
  • 9d6f2d2 docs: handoff — pairing prompt / IP drift / zombie bridge
  • 34adf28 fix: IP-independent pairing key fallback; run commands off the paho thread
  • f7422c9 fix: survive command exceptions; TV DHCP-reserved so pairing key stays valid

Handoff Chain

  • Continues from: 2026-10-23-003809-pairing-fix-verified.md
    • Previous title: pairing-prompt / zombie-bridge fix — verified on→off→on
  • Supersedes: None. The previous handoff's open questions (the key fallback across an IP change is still unverified; the Omada reservation didn't stick) still stand and are restated below.

Current State Summary

Seth asked to "claim the 3 open bugs and fix them". They are the hermes codex reviewer's findings for lgtv, not Gitea issues. All three are fixed in cc0e023 (pushed) and deployed to /usr/local/bin/lgtv_mqtt.py. lgtv-mqtt.service restarted at 11:05:43, reconnected cleanly and reported state ON. The hermes store now shows lgtv with 3 fixed and 0 open. Nothing is in progress.

Codebase Understanding

Architecture Overview

Unchanged from the previous handoff: Google Home → HA → Mosquitto → lgtv_mqtt.py → lgtv.sh. New this session: every call to lgtv.sh goes through run(), which now turns subprocess.TimeoutExpired into ("timeout", 124). No caller can get an exception from it any more.

Critical Files

File Purpose Relevance
lgtv_mqtt.py MQTT bridge run() timeout guard; handle_command checks the ok result
tests/test_bridge.py Replays the reviewer's 3 repros without a broker or TV Run: sudo -u seth python3 tests/test_bridge.py → ok
~/bin/hermes/state/reviewer/findings/lgtv/codex_bugs/ Hermes findings store for this repo Where "open bugs" live; Seth's daily Telegram digest counts these
~/bin/hermes/bin/hermes-findings Findings lifecycle CLI list/stats/fix/wontfix/apply-trailers --repo lgtv

Key Patterns Discovered

  • "Open bugs" = hermes findings, not Gitea issues. The lgtv Gitea repo has never had an issue. Findings are .md files whose status lives in an optional frontmatter block (no block = open).
  • Closing findings: put Fixes-finding: <slug> trailers in the commit message, then pipe it in: git log -1 --format=%B | ~/bin/hermes/bin/hermes-findings apply-trailers --repo lgtv --sha <sha>. lgtv has no post-commit hook that does this automatically (vdj does).
  • There is no "claimed" status. The statuses are open/fixed/wontfix/duplicate/invalid.
  • The reviewer can lag the code. Its 10-22 23:03 pass predates 34adf28, so one finding was already half fixed. Check against HEAD before you fix.

Work Completed

Tasks Finished

  • Located the findings (after first wrongly checking Gitea issues and reporting none)
  • Timeout: guard in run(). It covers the poll loop and on_connect, which 34adf28 had left exposed.
  • False success state: when a command fails, publish a fresh get_tv_state() probe instead of the requested state
  • Malformed payload: decode(errors="replace"). safe_handle from 34adf28 already kept the paho thread alive.
  • Test fails on the old code and passes on the new
  • Deployed, restarted, journal healthy; findings marked fixed via trailers

Files Modified

File Changes Rationale
lgtv_mqtt.py run() try/except; handle_command restructured One guard where every caller goes through
tests/test_bridge.py new The repo's single regression check

Decisions Made

Decision Options Considered Rationale
Catch the timeout in run() a guard in each caller Smallest diff; fixes every path at once
Publish the probed state when a command fails keep the last state; publish nothing Reports reality; the probe is cheap

Pending Work

Immediate Next Steps

  1. Nothing required.
  2. Known limit: get_tv_state() returns OFF when the status probe itself fails, so on a flaky network a failed OFF can still show OFF. Fix it only if it causes trouble.
  3. Carried over: check whether the TV accepts the fallback key after a real IP change, and find out why the Omada reservation for .20 didn't stick.

Blockers/Open Questions

  • Fallback key across an IP change is still unverified (from the previous handoff)
  • Omada reservation not applied (from the previous handoff)

Deferred Items

  • A post-commit hook in lgtv that runs apply-trailers automatically. It wasn't needed for 3 findings.

Context for Resuming Agent

Important Context

  • When Seth says "open bugs" for a repo, look in ~/bin/hermes/state/reviewer/findings/<repo>/codex_bugs/ first.
  • Hermes CLAUDE.md: its agents are read-only. Marking finding status through hermes-findings is the designed workflow.

Assumptions Made

  • Reporting the probed state after a failed ON is better than the old optimistic ON. WoL rarely fails at the script level.

Potential Gotchas

  • Run the test as seth (sudo -u seth), because paho is installed for that user.
  • The journal needs sudo: sudo journalctl -u lgtv-mqtt.service.
  • Re-run install.sh (or sudo install -m 0755 lgtv_mqtt.py /usr/local/bin/) after editing the bridge.

Environment State

Tools/Services Used

  • ~/bin/hermes/bin/hermes-findings, journalctl -u lgtv-mqtt.service

Active Processes

  • lgtv-mqtt.service on steel141, restarted 2026-10-24 11:05:43 with cc0e023.

Environment Variables

  • MQTT_PASSWORD (from /etc/lgtv/lgtv.env; name only)
  • ~/bin/hermes/src/hermes_glue/findings_status.py (status and trailer format)
  • Backups: lgtv/.backup/lgtv_mqtt.py.* (repo copy and deployed copy before the change)